我正在写一个家谱应用程序,我正试图弄清楚我的数据库模型的方面。
我有一张桌子供人们使用:
create table person (
id int unsigned not null primary key
)
我有一张名字表:
create table name (
id int unsigned not null primary key,
person_id int unsigned not null,
first_name varchar(191),
last_name varchar(191),
foreign key (person_id) references person (id)
)
一个人可以有多个名字,因为有时他们在不同的人口普查和其他记录中有不同的名字。
但是一个人也有一个我们应该默认显示的特定名称。
我的第一个想法是在表primary
中添加name
列:
create table person (
id int unsigned not null primary key
)
create table name (
id int unsigned not null primary key,
person_id int unsigned not null,
first_name varchar(191),
last_name varchar(191),
`primary` tinyint(1) not null default 0,
foreign key (person_id) references person (id)
)
这存在数据完整性问题。属于单个人的多个名称可以设置primary
标志。
我想到的另一种方法是在primary_name_id
表中添加person
列。这可以链接回name
表中的主要名称:
create table person (
id int unsigned not null primary key,
primary_name_id int unsigned default null,
foreign key (primary_name_id) references name (id)
)
create table name (
id int unsigned not null primary key,
person_id int unsigned not null,
first_name varchar(191),
last_name varchar(191),
foreign key (person_id) references person (id)
)
这也存在完整性问题。 primary_name_id
可能指向属于其他人的名称行。此外,它要求primary_name_id
列可以为空,因为当第一个人创建时,他还没有名字。
我想到这样做的第三种方式是在人物记录中包含“名称”字段的副本:
create table person (
id int unsigned not null primary key,
first_name varchar(191),
last_name varchar(191),
)
create table additional_name (
id int unsigned not null primary key,
person_id int unsigned not null,
first_name varchar(191),
last_name varchar(191),
foreign key (person_id) references person (id)
)
这似乎也不是一个理想的解决方案。类似的数据存储在两个地方。改变一个人的主要名称也需要一些工作。我必须插入一个新的additional_name,更新该人,并删除一个旧的附加名称。
有更好的方法吗?
答案 0 :(得分:1)
你的第二种方法基本上是正确的方法。但是,您希望确定该名称适用于此人。所以:
create table person (
id int unsigned not null primary key,
primary_name_id int unsigned default null,
foreign key (id, primary_name_id) references name (person_id, id)
);
create table name (
id int unsigned not null primary key,
person_id int unsigned not null,
first_name varchar(191),
last_name varchar(191),
foreign key (person_id) references person (id),
unique (person_id, id);
);
unique
约束有点冗余,但是让你确保两个表中的值匹配 - 恰当。