Mysql自动增量替代品

时间:2010-07-27 17:22:36

标签: database database-design mysql

我有下表。

create table mytable(
physical_id int auto_increment,
logical_id int,
data varchar(20),
version_start_date datetime,
version_end_date datetime,
primary key(physical_id),
unique key(logical_id,version_start_date, version_end_date)
);

架构背后的想法是,我想跟踪修改 通过选中,每行并在任何特定日期找到有效行 version_start_date和version_end_date。我想要我的逻辑id auto_increment,但是mysql只允许一个id为auto_increment。

因此,我想在创建新行时将logical_id设置为physical_id。一世 能够使用触发器来完成它。

delimiter $$
create trigger myTrigger before insert on mytable for each row begin set 
new.logical_id = (select auto_increment from information_schema.tables 
where table_schema = database() and table_name = 'mytable') ; end$$
delimiter ;

我检查的其他选项很少,http://feedblog.org/2007/06/20/portable-sequence-generation-with-mysql/http://www.redhat.com/docs/en-US/JBoss_Hibernate/3.2.4.sp01.cp03/html/Reference_Guide/Native_SQL-Custom_SQL_for_create_update_and_delete.html

这些方法的问题是,我必须创建一个新的序列表并继续在该表中插入记录。

有更好的选择吗?

谢谢你 巴拉

-- Update

我不知道为什么@tpdi,为什么我需要父母,当我可以用下表来模仿它时。

create table logical_id_seq (
 logical_id int auto_increment,
primary key(logical_id)
);

create table mytable (
physical_id int auto_increment,
logical_id int not null references parent(logical_id),
data varchar(20),
version_start_date datetime not null,
version_end_date datetime not null,
primary key(physical_id),
foreign key (logical_id) references logical_id_seq(logical_id),
unique key (logical_id,version_start_date,version_end_date)
);

4 个答案:

答案 0 :(得分:1)

这就是为什么我更喜欢Oracle / PostgreSQL序列到MySQL的auto_increment和SQL Server的IDENTITY - 你可以为此定义多个序列。

为一个列创建一个单独的表,以便将auto_increment用于额外的auto_increment,这是我能想到的最佳解决方案,可通过触发器或存储过程访问。

答案 1 :(得分:0)

为什么你不希望有一个包含当前版本的表,然后是一个历史记录的附加表?然后,使用插入当前版本表来生成您的ID,并仅在您确实需要历史信息时查询历史记录表。

答案 2 :(得分:0)

现在我明白你的问题:)。改变我的回答。

您需要使用一些触发器,以便每当编辑某行时,逻辑ID增加1,查找表中可用的最大逻辑ID。

答案 3 :(得分:0)

create table parent (
  logical_id int auto_increment,
  physical_id int null references mytable(id)
);


create table mytable(
  physical_id int auto_increment,
  logical_id not null references parent(logical_id),
  data varchar(20),
  version_start_date datetime,
  version_end_date datetime,
  primary key(physical_id)
);

要插入现有记录的新实例,请插入mytable ....,然后捕获新的mytable.id,并使用它更新父级的physical_id(可能在触发器中)。

现在,要查找当前记录,请在父级中查找逻辑ID,并使用parent.physical_id加入“mytable”中的正确记录

父母指向“mytable”中的当前有效记录(所有记录)。

要查找逻辑记录的所有实例,请使用“mytable”中的logical_id。

要插入全新的记录,首先插入父级以获取新的logical_id,然后将数据插入“mytable”;这就是我们允许parent.physical_id可以为空的原因。

关于OP的更新:是的,您可以通过“窃取”序列来“模拟”,但这并不能模拟实际发生的事情。 “窃取”序列只是一个实现细节;如上所示,有两个表格可以明确说明真正发生的事情,即:我在“mytable”中有一个当前状态(哪个父指向),在“mytable”中有0,1或多个先前状态。这是一个更清晰的关注点分离,一个告诉你“任何id的当前状态”的表,以及一个告诉你“当前状态的数据和先前状态的数据”的表。