我正在设计一个数据库,但是我现在遇到了一个难题,
目前我有3个表:
- ex_artists
- ex_tracks
- ex_labels
现在我希望在这3个(或更多)表中有一个唯一的ID
所以如果"示例艺术家"的ID为"1",那么"示例轨道"的ID不能为"1"但应该得到ID '2',因为'1'已经存在
我理解你的担忧。一旦您决定使用技术id来设计数据库,总是存在混淆id的危险。而
insert into album_track (album, artist, track, no)
values ('B0016991-00', 'JBIEBER', 'BOYFRIEND0001', 2);
代替
insert into album_track (album, artist, track, no)
values ('B0016991-00', 'BOYFRIEND0001', 'JBIEBER', 2);
可能会出错,
insert into album_track (album_id, artist_id, track_id, no) values (40, 22, 12, 2);
不是insert into album_track (album_id, artist_id, track_id, no) values (40, 12, 22, 2);
可能不会,而且当您注意到程序错误时,可能已经来不及区分好记录和坏记录了。你的数据在技术上是一致的,但实际上是一团糟。
为了克服这个问题,您需要一个源来提取您的id。例如,在Oracle中,您将使用序列。在MySQL中,你可以为这个目的创建一个ID表:
create table ids(id int auto_increment primary key);
create table album(id int primary key, album_no text, album_name text,
foreign key (id) references ids(id));
create table track(id int primary key, track_name text, record_date date, take int,
foreign key (id) references ids(id));
insert into ids values ();
insert into album (id, album_no, album_name) values
((select last_insert_id), 'B0016991-00', 'Justin Bieber – Believe - Deluxe Edition');
因此,每当您在其中一个表中插入一条记录时,您必须指定一个ID(因为它不会自动获取)。你通过插入到ID表中获得ID,然后调用MySQL的LAST_INSERT_ID()。
一个不太安全,但更简单的替代方法是在不同的偏移量开始id:
create table album(id int auto_increment primary key, album_no text, album_name text);
create table track(id int auto_increment primary key, track_name text, record_date date);
alter table track auto_increment=10000001;
create table artist(id int auto_increment primary key, artist_name varchar(100));
alter table artist auto_increment=20000001;
insert into artist (artist_name) values ('Justin Bieber');
只要您的id保持在所需的范围内,这就可以工作。
不是我没看你写的
,但你不需要一个唯一的ID,只需要唯一的方式来标识行。
考虑以下内容:
-- drop table artist
create table artist
(
artist_id int unsigned auto_increment PRIMARY KEY,
artist_name varchar(255) not null
);
insert into artist (artist_name) values ('U2');
insert into artist (artist_name) values ('Cranberries');
-- drop table label
create table label
(
label_id int unsigned auto_increment PRIMARY KEY,
artist_id int not null, -- will leave FK RI to developer
label_name varchar(255) not null,
release_date datetime not null
);
insert into label(artist_id,label_name,release_date) values (1,'Boy','1980-10-20');
insert into label(artist_id,label_name,release_date) values (2,'No Need to Argue','1994-10-03');
create table track
(
id int unsigned auto_increment PRIMARY KEY, -- not completely necessary, will explain
track_id int not null, -- u number this 1 to n consistent with label layout
label_id int not null, -- will leave FK RI to developer
track_name varchar(255) not null
);
-- Cranberries:
insert track (track_id,label_id,track_name) values (1,2,'Zombie');
-- U2:
insert track (track_id,label_id,track_name) values (1,1,'I Will Follow');
insert track (track_id,label_id,track_name) values (2,1,'Twilight');
-- select * from track
艺人和厂牌相当明显。Track不需要"id"列,但我还是把它加了进去。也就是说,track可以被识别为艺人/厂牌id
的组合。外键(FK)引用完整性由您决定,但如果您需要,我可以添加