Database Mysql自动增量替代方案

Database Mysql自动增量替代方案,database,database-design,mysql,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) ); create tabl

我有下表

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)
);
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)
);
模式背后的想法是,我想跟踪对 并通过检查 版本开始日期和版本结束日期。我希望我的逻辑id是 自动递增,但mysql只允许一个id自动递增

因此,我想在创建新行时将逻辑_id设置为物理_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 ;
我签出的其他选项很少,而且

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

有更好的选择吗

谢谢你
巴拉

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

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)
);
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)
);

为什么不希望有一个当前版本的表,然后有一个历史记录的附加表?然后,在当前版本表中使用insert来生成ID,并且只有在实际需要历史信息时才查询历史表。

这就是为什么我更喜欢Oracle/PostgreSQL序列而不是MySQL的自动增量和SQL Server的标识-您可以为此定义多个序列


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

现在我理解了您的问题:)。改变我的答案

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

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,并用它更新父级的物理id(可能在触发器中)

现在,要查找当前记录,请在parent中查找逻辑id,并使用parent.physical\u id连接到“mytable”中的正确记录

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

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

要插入一个全新的记录,首先要插入到父项中以获取新的逻辑_id,然后在“mytable”中插入数据;这就是为什么我们允许parent.physical_id为空


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

我希望我的数据库在某种意义上是时间无关的,数据库中的数据在任何时间点都是有效的。查找max可能会导致竞争条件,并最终损坏数据。实际上,我想设计一个时间旅行数据库,因此没有当前状态的概念。很抱歉,我没有提到,但是版本开始日期和结束日期用于在任何时间点查找状态。希望现在天气转晴。谢谢@tpdi.“时间旅行”数据库,你指的是暂时的,也称为“第六范式”数据库吗?