在 MySQL 中,是否可以在两个不同的表中拥有一个自动递增的列?示例:table1 有一个“secondaryid”列,table2 也有一个“secondaryid”列。是否可以让 table1.secondaryid 和 table2.secondaryid 保存相同的信息?像 table1.secondaryid 可以保存值 1、2、4、6、7、8 等,而 table2.secondaryid 可以保存值 3、5、9、10?这样做的原因是双重的:1)这两个表将在一个单独的“喜欢”表中引用(类似于用户在 facebook 上喜欢一个页面)和 2)table2 中的数据是 table1 使用主键的子集。因此,table2 中包含的信息取决于 table1,因为它们是不同类别的主题。(类别为 table1,主题为 table2)。
7 回答
您似乎想在两个单独的表中区分类别和主题,但在另一个表中引用它们的 idlikes
以方便用户喜欢类别或主题。
您可以做的是创建一个包含子类型categories
和topics
. 自动递增的键将在超实体表中生成,并仅插入两个子类型表之一(基于它是类别还是主题)。
子类型表通过 1:1 关系中的自动递增字段引用此超实体。
这样,您可以简单地将超实体表链接到likes
仅基于一列的表(可以表示类别或主题),并且id
在子类型表中都不会出现。
这是一个简化的示例,说明如何对此进行建模:
此模型将允许您维护类别和主题之间的关系,但在superentity
表中概括了这两个实体。
此模型的另一个优点是您可以将子类型表中的公共字段抽象到超实体表中。例如说categories
andtopics
都包含字段title
和url
: 您可以将这些字段放在superentity
表中,因为它们是其子类型的公共属性。仅将特定于子类型表的字段放入子类型表中。
您不能在表之间共享 auto_increment 值,但您可以让它看起来是:
set @@auto_increment_increment=2; // change autoinrement to increase by 2
create table evens (
id int auto_increment primary key
);
alter table evens auto_increment = 0;
create table odds (
id int auto_increment primary key
);
alter table odds auto_increment = 1;
这样做的缺点是您正在更改全局设置,因此所有auto_inc 字段现在将增长 2 而不是 1。
如果您只是希望两个表中的 ID 不同,您可以最初将 table2 的 AUTO_INCREMENT 设置为某个大数字。
ALTER TABLE `table2` AUTO_INCREMENT=1000000000;
听起来你想要一个 MySQL 等价的序列,可以在 DBMS 中找到,比如 PosgreSQL。有一些已知的方法,其中大部分涉及创建跟踪序列名称的表和保持当前值的整数字段。这种方法允许您查询包含序列的表,并在必要时在一个或多个表上使用它。
这里有一篇文章对这个问题有一个有趣的方法。我还在DB PEAR 模块中看到了这种方法,它现在已经过时了。
您需要通过客户端或在 mysql 内部通过 sql 函数手动设置另一个表的增量值:
ALTER TABLE users AUTO_INCREMENT = 3
因此,在插入 table1 之后,您将返回最后一个自动增量,然后通过该值修改另一个表的自动增量字段。
你可以用触发器做到这一点:
-- see http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
CREATE TABLE sequence (id INT NOT NULL);
INSERT INTO sequence VALUES (0);
CREATE TABLE table1 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
secondardid INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
CREATE TABLE table2 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
secondardid INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
DROP TRIGGER IF EXISTS table1_before_insert;
DROP TRIGGER IF EXISTS table2_before_insert;
DELIMITER //
CREATE
TRIGGER table1_before_insert
BEFORE INSERT ON
table1
FOR EACH ROW
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
NEW.secondardid = LAST_INSERT_ID();
END;
//
CREATE
TRIGGER table2_before_insert
BEFORE INSERT ON
table2
FOR EACH ROW
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
NEW.secondardid = LAST_INSERT_ID();
END;
//
我对你的问题感到困惑。如果表 2 是表 3 的子集,为什么要让它共享主键值。您的意思是表 2 和表 3 之间的类别是分开的吗?
如果是这样,我会质疑将它们放入单独表格的设计选择。听起来你有两种不同的情况之一。首先是你有一个“类别”实体,它有两种风格。在这种情况下,您应该有一个单独的类别表,可能带有一个指定类别类型的类型列。
第二个是你的用户可以“喜欢”不同的东西。在这种情况下,“用户喜欢”表应该为每个对象有一个单独的外键。您可以使用复合外键完成一个技巧,之后您将拥有对象的类型和常规的数字 id。因此,like 表将具有“type”和“id”。person 表将有一列填充“PERSON”,另一列填充数字 id。连接会说“在 a.type = b.type 和 a.id = b.id 上”。(或者“类型”上的部分可能是隐含的,在表的选择中)。