2011-12-10 19 views
3

私はデータベースの設計に関して非常に基本的な質問があります。私は答えを知っていると思っていましたが、トリプルドロップダウンメニューとデモデータベースのデザインに関するオンラインチュートリアルを見た後、私はそれ以上は分かりません。データベース設計101

ここでは、セットアップには3つのテーブルがあります。

まずテーブル:tblcountry フィールド: 国をCOUNTRY_ID

第二表:tblstate フィールド: COUNTRY_ID 状態

第三のテーブルをSTATE_ID:tblcity フィールド:cidy_id は 市

をSTATE_ID今私の質問は次のとおりです:表3では、カントリードも含める必要がありますか? SQLを使用すると、都市がどの国にあるかを照会することができます。または、都市表で国を参照するのは良い設計ですか?私は誰かが表3で

答えて

1

正規化は、データで始まります。以下では、の状態をゆっくりと取ります。私は、データ分析と正規化について話しています。政治階層のモデリングについてではありません。

country_name    state_name city_name 
-- 
United States of America Alabama  Birmingham 
United States of America California Atascadero 
United States of America Florida  Key Largo 
United States of America Illinois Carbondale 
United States of America Kentucky Winchester 
United States of America Michigan St. Louis 
United States of America Ohio  Coldwater 
United States of America Montana  Glasgow 
United States of America Louisiana Jefferson 
United States of America Wisconsin Jefferson 
Bulgaria     Montana  Montana 
Costa Rica     San José San José 
Argentina     Entre Rios San José 
Uruguay     San José San José de Mayo 

「市[country_name]は国[country_name]の州[state_name]にあります」という意味です。 (表が意味するものはその述語と呼ばれます)

この表は、都市の「完全名」を{country_name、state_name、city_name}として効果的に識別します。概念レベルでは、{last_name、middle_name、first_name}を使用して人物を識別することとあまり変わりありません。違いは、2人の人が同じフルネームを共有することはよくありますが、2つの都市は同じではありません。

{country_name、state_name、city_name}の候補キーは1つだけです。この表は5NFです。テキストにID番号を代入してもそれを変更することはできません。

は今、あなたが5NFにテーブルを正規化してきました後のあなたは思い最初の事何だ、そのテーブルには、「すべてのキー」であることが判明しますか?それで、 "Ok、nowキーをさらに分割する必要がありますか?

私は願っていません。

データの整合性を高めるには、projectの列の分かりやすいサブセットを設定し、外部キー参照を設定します。この方法で使用される投影法は、元の表の通常の形には全く影響しません。このような投影の前に2NFであった場合、この種の投影後に2NFになります。これらの表は、元の表とは少し異なる述語を持っています。 (当たり前。)

-- Predicate: "State [state_name] is in country [country_name]." 
-- This table is also in 5NF. 
create table states (
    country_name varchar(35) not null, 
    state_name varchar(15) not null, 
    primary key (country_name, state_name) 
); 

insert into states 
select distinct country_name, state_name 
from cities; 

alter table cities 
add constraint cities_fk1 
foreign key (country_name, state_name) 
    references states (country_name, state_name); 

-- Predicate: "[country_name] is a country." 
-- This table is also in 5NF. 
create table countries (
    country_name varchar(35) primary key 
); 

insert into countries 
select distinct country_name 
from states; 

alter table states 
add constraint states_fk1 
foreign key (country_name) 
    references countries (country_name); 

ドロップダウンリストを移入するための国を選択するには、あなただけの

select country_name 
from countries 
order by country_name; 

ユーザーが国を選択したことができ、状態を選択すると簡単です。

select state_name 
from states 
where country_name = '?' 
order by state_name; 

都市名の選択は似ています。

select city_name 
from cities 
where country_name = '?' 
    and state_name = '?' 
order by city_name; 
+0

私はあなたが何を意味するのか見ていますが、最初に表示されたテーブルでは、州の中に2つのcity_name値があったらどうなりますか?あなたがそれを設定する方法は、それをさらに正規化すべきではないと論理的に思えますが、それをさらに引き上げてデータを追加する場合は、もう1つのテーブルが必要ですか?または私は間違っていますか?私はこのすべてに非常に新しいです:-) – user1088537

+0

@ user1088537:キーは{country_name、state_name、city_name}です。あなたは特定の州の任意の数の異なる都市名を持つことができます。そのテーブル*は、同じ州の2つの都市を同じ州で認めていません。私はSQLデータベースのアドレスを25年間使ってきました。私は同じ州の2つの都市を見たことがありません。 (私はある州に同じ名前の2つの名前のついた場所を見たことがありますが、それらは同じものではありません)。 –

3

:-)役立つことを願って

、それは同様にcountryidを含める必要がありますか?

あなたは次のクエリ使用してcounty_idを得ることができます。データが複製されるため、

SELECT country_id 
FROM tblcity c 
INNER JOIN tblstate s ON (c.state_id = s.state_id) 

あなたがを行う場合は、データベースが正規形に違反し、市内テーブルのcountry_id含んをデータが同期しなくなる危険性があります。例えば。 tableCitycountry_idtableStateのそれと一致しないとどうなりますか。

あなたが国の名前を取得したい場合は、あなたが同様に国が参加する必要があります:city-> state -> countryないすべての国があり、非常に米国中心のビューである:

SELECT co.country 
FROM tblcity ci 
INNER JOIN tblstate s ON (ci.state_id = s.state_id) 
INNER JOIN tblCountry co ON (s.country_id = co.country_id) 

はまた部門があることに注意してくださいそのように分かれている国では、4つのレベルの階層が必要です。

+0

ありがとうございます!それが私の疑惑を確認します。私は、必要に応じて3つのテーブルをすべて組み合わせたビューを作成できることは知っていましたが、この設定を見て私はかなり混乱していました。 私は実際にはファーム名を持つデータベースで作業しています。したがって、これらのテーブルは私のニーズに合っています。最初の2つのテーブルはここの最初の2つのテーブルと同じくらいシンプルになりますが、私の "city"テーブルにはgps座標などのフィールドが多く含まれています。 – user1088537

6

時間の99.9%が正しく答えられました:いいえ、あなたはすでに状態記録を介して国への参照を持っています。

長い答え:0.1%の時間について:国の都市について多くの質問をしているため、都市の国を直接参照する必要があるかもしれません。クエリを実行するとクエリの実行時間が長くなります。

この2番目のシナリオは、都市、州、国のレコードセットには適していませんが、他のタイプのデータでは、多くのレコードを管理している可能性があります。

編集私の仕事では、テーブルの余分なフィールドを3つまたは4つのレベルの参照にしているだけです。これらは巨大なデータベースであり、すべての一般的なクエリに中間テーブルを置くと、実際にはデータベースに負荷がかかります(クエリごとに使用されるメモリが非常に多い)。だから私は直接参照なしで始め、必要に応じて "ショートカット"フィールドを追加します。これはスケーラビリティの問題を解決するという問題になり、それは初心者レベルの問題を超えています。また、川下のテーブルにショートカットフィールドを追加すると、それはアプリのもう一つの破壊点です(都市を別の国に更新すると2つのレコードが更新されます)。

+0

ありがとう!それは私が思ったことであり、私がこれを調べたすべての書籍から推測できるものです。チュートリアルの笑でこの設定を見るのは本当に混乱しました。ちょうど私のデータベース設計知識がどれほどかを示しています;-) – user1088537