質問

私には意見の質問がありますが、同時に正しい答えがあるかもしれません。私は一連の製品を開発しようとしていますが、自分でやっているので、初めて正しくやっていることを確認したいと考えています。スキーマを複数回書き直しましたが、そのたびにそれがより良いと思うたびに。それから私はいくつかの新しいアイデアに出くわすことができ、それはスキーマに関する多くの作業を必要とするか、それが私のスキーマを破るでしょう。

大学では、「合理化」(それが彼らが使用した言葉だと思いますが、はるかに離れている可能性がある)について学び、5つのレベルがあります。私が覚えていることから、レベル3が最も一般的でした。私は、練習がデータが繰り返されないことを確認することであり、それを行うために、テーブルを小さなテーブルに分割する必要がありました。そして、あなたがそれをどこまで壊したかに応じて、レベルは高くなりました。まあ、私は最高レベルが欲しいかどうかはわかりませんが、私はそれを手に入れることができるのと同じくらい効率的にしたいことを知っています。私は4年間のSQL Server 2000/2005/2008と2年間のOracle、約6か月間(5年以上前)で、MySQLと約6か月のアクセスを備えたOracle(5年以上前)を獲得しました。私の好みはSQL Serverですが、どちらのプラットフォームでもスキーマを効率的にしたいと思います。

これがいくつかのテーブルのPsuedoスキーマレイアウトです。それから私がやりたいことを説明します。

Manufacturers
  ManufacturerID (Identity)
  ManufacturerName
  ManufacturerStreetAddress
  ManufacturerZipCodeID
  ...

ZipCodes
  ZipCodeID (Identity)
  ZipCode
  ZipCodeStateID
  ...

States
  StateID (Identity)
  StateName
  StateAbbreviation
  ...

Cities
  CityID (Identity)
  CityName
  CityStateID
  ...

Psuedoスキーマだけであることをお詫びしますが、休憩中に紙の上でデザインをしているので、それは今私が持っているすべてですが、行き過ぎる前に質問がありました。私がやりたいのは、すべてがお互いに適切に結びついていることを確認することです。私の信念は、ジップコードは州と都市に属しているが、1つのジップコードに属していない都市はありません。 ZIPコードを製造業者のテーブルに入れた場合、州と都市を手に入れることができます。しかし、私は他のテーブルで何度もIDを使用したくありません。つまり、ジップコードや都市にステートディッドがいることは何度もあるかもしれません。州は同じ名前の複数の都市を持つことができ、複数の州に同じ名前の都市を持つことができます。しかし、CityNamesテーブルとCityStatesテーブル(CityNameidとStateID)が必要かどうかはわかりません。購入するためにロケーションデータベースがあること、たぶん無料で、これを心配する必要がないことをよく知っています。しかし、私はこれを理解することに取り組みたいと思います。なぜなら、それは将来的にはスキーマのデザインに賢明なデザインに役立つと信じているからです。

質問:

  1. そのpsuedoスキーマは、それが正しいと思われるのですか、それともより良いかもしれない(意見)?
  2. データベースを「合理化」するのか、それとも何か他のものと呼ばれていますか(正しい答えに投票します)?そして、どこまで遠すぎるか(意見)
  3. また、ユーザーテーブルやアドレス(チーム、国会議事堂など)を含むその他のテーブルもありますので、Psuedoスキーマは、理論で正しい場合、そのようなデータベースの良い計画です(意見)?

お時間をいただきありがとうございます。徹底的で一貫性のある回答を投票します。データベースの専門家または長年のデータベース経験を持つ人々が望ましいですが、私はすべての答えを聴きます。また、これがコミュニティウィキであるべきかどうかはわかりませんが、私は今それをマークしていません。ありがとう。

アップデート: :また、データベースが「合理化」することで、結合、時にはサブクリーリーの必要性があることを知っていることを忘れていました。私は通常、左外の結合を悪用しますが、4つの異なるクエリを実行するのではなく、これらのテーブルを結び付けるためにアドレスを表示する最も効率的な方法は何ですか?ありがとう。

アップデート: :OK、今ではこれはあまりにも正規化されているか、十分に正規化されていないか、まったく正規化されていないかもしれませんが、このpsuedoスキーマが好きかどうか教えてください。

Manufacturers
  ManufacturerID (Identity)
  ManufacturerName
  ManufacturerStreetAddress
  ManufacturerCCSZID --CCSZ (Country, City, State, Zip), needs a better name
  ...

ZipCodes
  ZipCodeID (Identity)
  ZipCode
  ...

States
  StateID (Identity)
  StateName
  StateAbbreviation
  ...

Cities
  CityID (Identity)
  CityName
  ...

Countries
  CountryID (Identity)
  CountryName
  CountryAbbreviation
  ...

CountryCityStateZipCodes
  CountryCityStateZipCodeID (Identity)
  CCSZCountryID
  CCSZStateID
  CCSZCityID
  CCSZZipCodeID

そして、住所を取得するには、次のようになります。

SELECT  M.ManufacturerStreetAddress,
        CN.CountryName,
        CN.CountryAbbreviation,
        S.StateName,
        S.StateAbbreviation,
        C.CityName,
        Z.ZipCode
FROM Manufacturers M
LEFT OUTER JOIN CountryCityStateZipCodes CCSZ ON CCSZ.CountryCityStateZipCodeID = M.ManufacturerCCSZID
LEFT OUTER JOIN Countries CN ON CN.CountryID = CCSZ.CCSZCountryID
LEFT OUTER JOIN States S ON S.StateID = CCSZ.CCSZStateID
LEFT OUTER JOIN Cities C ON C.CityID = CCSZ.CCSZCityID
LEFT OUTER JOIN ZipCodes Z ON Z.ZipCodeID = CCSZ.CCSZZipCodeID

または、皆さんがそのクエリを書くより良い方法を知っているかもしれません。しかし、とにかく、それは最初のスキーマよりも良く見えますか?

役に立ちましたか?

解決

私はいつも「正規化」と呼ばれると聞いていますが、私たちは同じことについて話しています。

最も簡単なことは、都市、州、ジップを1つのテーブルに組み合わせることです。郵便番号自体をキーとして使用することも検討することもできますが、それを避けたい2つの理由を考えることができます。

  1. 北東の州には、0から始まる郵便番号があります。これは、郵便番号を数値フィールドにすると切り捨てられます。
  2. 郵便番号をキーとして使用する場合、複数の町で何度もそのジップを持つことはできません。あなたが言ったように、郵便局は町の名前よりもジップを気にしています。しかし、このセットアップは、後でそれらの個々の町を検索することを制限します。

後で市、州、またはジップで検索するには、このテーブルをメーカーテーブルに参加させてください。メーカーZipCodeIDが空白のメーカーテーブルにフィールドがある場合を除き、内側の結合を使用しても大丈夫です。その場合、それらも表示するために左結合が必要です。

他のヒント

私はあなたが物事をセットアップする方法にあまり問題はありません。郵便番号の状態IDは危険かもしれません - 状態の境界を越えて郵便番号があることを知ることは驚くことではありませんが、それについてはわかりません。

州、都市、郵便番号を別々のテーブルに保存することで多くの参加を行いますが、一貫性の測定なしでアドレスを保存したデータベースを扱ったことで、それは数人の結合よりもはるかに悪夢のようです。たとえば、「NY」、「NY」、「NY」、「New York」と「NewYork」になります。したがって、州、都市、ジップのための別のテーブルが長期的には報われると思います。

私はデータベースの専門家ではありませんが、私の観点では、与えられた擬似スキーマは間違っているようです。これが説明です。問題から知られている事実は次のとおりです。

  1. 州には複数の都市があります。
  2. 状態はユニークです
  3. 都市には複数のzipコードがあります
  4. 都市名は別の都市名に等しいかもしれません。
  5. 郵便番号は一意です

まず、ユニークを書き留めます。したがって、これら2つの生のテーブルを作成します。

STATE
---
State ID (PK)
State Name

ZIP
---
Zip ID (PK)
Zip Code (NK)

次に、論理的な質問が生じます。 zip IDを知っていると、どのようにして都市IDを取得しますか?それに答えるには、ZipとCityの間にリンクを提供する必要があります。このリンクはどこに置くべきですか?事実#3から、都市には多くの異なる郵便番号があることがわかっているため、都市のテーブルにはありません。したがって、それはzipテーブルにある必要があります。これは、ZIPテーブルの次のバージョンです。

ZIP
---
Zip ID (PK)
Zip Code (NK)
City ID (FK)

これで、ZIPからCityに「移動」できるため、City Tableについて説明します。都市の名前は他の人と同じ名前を持つことができます。そのため、ユニークであるように強制する必要はありません(都市名フィールド)。これが私たちの都市テーブルの最初のバージョンです:

CITY
----
City ID (PK)
City Name

繰り返しますが、同じ論理的な質問が発生します。どのようにして都市を知っていることを州に移動しますか?これら2つのテーブルの間のどこかにリンクを作成する必要があります。繰り返しますが、事実#4を知ることは、都市名の独自性について何も保証することはできません。リンクは都市のテーブルに置く必要があります。これが私たちの次のバージョンの都市テーブルです:

CITY
---
City ID (PK)
City Name
State ID (FK)

このリンクを使用すると、状態を正しく取得できます。全体として、ZIPからCity ID(Zip Tableで提供)を介してZipからCityに移動することができ、市から州への移動を続けることができます(City Tableで提供)。

データベースの合理化はデータベースの観点からは適していますが、プログラミングの観点では「悪」と見なすことができます。プログラマーがますます多くのクラスを書くようにプッシュするからです。結局のところ、「あまりにも遠い」は「テーブルが非合理的になる」と定義できます。都市名のテーブルは、エンティティではなく属性であるため、非合理的なようです。私のデータベースアナリストがそのような不合理なテーブルを作成した場合、私は喜んで「あまりにも遠く」にラベルを付けます:)一方、過剰合理化データベースはデータベースのパフォーマンスに大きな影響を与える可能性があります。私の経験から、それはクエリの実行を遅くします。

ユーザー、チーム、国会議事堂などの別の問題については、まだ問題を見ていないので、今のところ何も言えません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top