我有下表。
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)
);
答案 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的当前状态”的表,以及一个告诉你“当前状态的数据和先前状态的数据”的表。