将“唯一一条记录”标记为“主要”

时间:2017-03-01 02:01:29

标签: mysql sql

我正在写一个家谱应用程序,我正试图弄清楚我的数据库模型的方面。

我有一张桌子供人们使用:

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,更新该人,并删除一个旧的附加名称。

有更好的方法吗?

1 个答案:

答案 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约束有点冗余,但是让你确保两个表中的值匹配 - 恰当。