2017-03-01 6 views
0

私は系図アプリケーションを作成しています。私はデータベースモデルの側面を理解しようとしています。「プライマリ」として1つだけを記録します

私は人用のテーブルがあります。

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

人は複数の名前を持つことができます記録。

しかし、人にはデフォルトで表示する必要がある特定の名前が1つあります。


私が最初に考えたのは、テーブルnameprimary列を追加しました:

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

これは、データの整合性の問題があります。 1人の個人に属する複数の名前には、primaryフラグが設定されている可能性があります。


私が考えるもう一つの方法は、personテーブルにprimary_name_id列を追加することでした。これは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列をNULL可能にする必要があります。これは、どちらかの理想的なソリューションのように見えるしていません

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


私はこれを行うことを考えた第三の方法は、個人レコードの「名前」フィールドの重複を含めることです。同様の種類のデータが2つの場所に格納されています。また、人のプライマリ名を変更するには少しの作業が必要です。私は新しいadditional_nameを挿入し、人を更新し、古い追加の名前を削除する必要があります。


これを行うより良い方法はありますか?

+2

'person'テーブルの' current_name_id'はどうでしょうか? – ceejayoz

+1

@ceejayozの提案は私にとって良さそうです。ただ一つの場所で現在の名前のIDを追跡してください。とにかく、現在の名前を追跡するために、 'name'テーブルの責任であってはならないかもしれません。むしろ、それぞれの人がこれを把握しておくべきです。 –

+0

@ceejayoz、私が正しく理解すれば、それは私の2番目に提案された解決策のようです。私は私の列 'primary_name_id'を呼び出しました。それは実際に私のデータベースが現時点でどのように設定されているかです。私の懸念は、 'primary_name_id'が間違った人に属する名前を指すことができるので、私は他のアイディアがあるのか​​疑問に思いました。 – Dave

答えて

1

2番目の方法は基本的に正しい方法です。しかし、あなたはその名前がその人のためであることを確かめたい。だから、:

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制約は、冗長性のビットですが、それはあなたが値2つのテーブル間で一致していることを確認してみましょう - 適切。

関連する問題