3

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

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

これがいくつかのテーブルの疑似スキーマレイアウトです。次に、私が何をしたいのかを説明します。

Manufacturers
  ManufacturerID (Identity)
  ManufacturerName
  ManufacturerStreetAddress
  ManufacturerZipCodeID
  ...

ZipCodes
  ZipCodeID (Identity)
  ZipCode
  ZipCodeStateID
  ...

States
  StateID (Identity)
  StateName
  StateAbbreviation
  ...

Cities
  CityID (Identity)
  CityName
  CityStateID
  ...

疑似スキーマに過ぎないことをお詫びしますが、休憩時間に紙でデザインをしているので、今はそれだけですが、行き過ぎる前に質問がありました。私がやりたいのは、すべてが適切に相互に結びついていることを確認することです。私の考えでは、郵便番号は州と市に属していますが、1つの郵便番号に属する市はありません。多くの郵便番号が含まれている可能性があります。郵便番号をManufacturersテーブルに入れると、州と市を取得できるようになります。ただし、他のテーブルでIDを何度も使用したくありません。つまり、ZipCodesとCitiesにStateIDがあるということは、何度も繰り返される可能性があるということです。州は同じ名前の複数の都市を持つことができ、複数の州は同じ名前の都市を持つことができます。しかし、CityNamesテーブル、次にCityStatesテーブル(CityNameIDとStateID)が必要かどうかはわかりません。私は、購入できるロケーションデータベースがあり、おそらく無料で使用でき、これについて心配する必要がないことをよく知っています。ただし、将来的にはスキーマの設計に役立つと思うだけでなく、何か変更が必要になった場合にレイアウトをカスタマイズできるようにしたいので、この理解に取り組みたいと思います。

質問:

  1. その疑似スキーマは、それ自体が正しいように見えますか、それとももっと良いでしょうか(意見)?
  2. それはデータベースの「合理化」と呼ばれていますか、それとも他の何か(正解に投票します)ですか?そして、どこまで遠すぎるか(意見)
  3. Usersテーブル、およびアドレス(Teams、Capitolsなど)を含む他のテーブルもあります。したがって、psuedoスキーマは、理論的に正しい場合、そのようなデータベース(意見)の良い計画になるでしょうか?

いつもありがとうございました。徹底的で首尾一貫した回答に投票します。データベースの専門家またはデータベースの長年の経験を持つ人が望ましいですが、私はすべての答えに耳を傾けます。また、これがコミュニティWikiであるかどうかはわかりませんが、現時点では1つとしてマークしていません。ありがとう。

更新:また、データベースの「合理化」により、結合や場合によってはサブクエリが必要になることを私は知っていることを忘れました。私は通常、LEFT OUTER JOINを悪用しますが、4つの異なるクエリを実行するのではなく、これらのテーブルを結合してアドレスを表示する最も効率的な方法は何でしょうか。ありがとう。

更新:わかりました。これは正規化されすぎているか、十分に正規化されていないか、まったく正規化されていない可能性がありますが、この疑似スキーマの方が好きかどうか教えていただけますか?

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

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

4

3 に答える 3

3

「正規化」と呼ばれることはよく耳にしますが、同じことを話しているのです。

最も簡単な方法は、都市、州、およびzipを1つのテーブルに結合することです。郵便番号自体をキーとして使用することも検討できますが、それを避けたい理由は2つ考えられます。

  1. 北東部の州には0で始まる郵便番号があり、郵便番号を数値フィールドにすると切り捨てられます。
  2. 郵便番号をキーとして使用する場合、複数の町でその郵便番号を複数回使用することはできません。あなたが言ったように、郵便局は町の名前よりも郵便番号を気にします。ただし、この設定では、後でこれらの個々の町を検索することはできません。

後で都市、州、またはzipで検索するには、このテーブルをManufacturersテーブルに結合するだけです。INNER JOINを使用しても問題ありません。ManufacturersテーブルにManufacturerZipCodeIDが空白のフィールドがない場合は、LEFTJOINでそれらも表示する必要があります。

于 2010-08-31T14:20:46.220 に答える
1

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

州、市、郵便番号を別々のテーブルに格納することで多くの結合を実行しますが、整合性対策なしでアドレスを格納するデータベースを扱っているため、いくつかの結合よりもはるかに悪夢です。たとえば、「NY」と「ny」と「Ny」と「NewYork」と「NewYork」になります。したがって、州、市、および郵便番号用に別々のテーブルを用意することで、長期的に見返りが得られると思います。

于 2010-08-31T14:30:58.390 に答える
1

私はデータベースの専門家ではありませんが、私の見解では、指定された疑似スキーマは正しくないようです。これが説明です。問題から知られている事実は次のとおりです。

  1. 州は複数の都市を持つことができます。
  2. 状態はユニークです
  3. 都市は複数の郵便番号を持つことができます
  4. 都市名は別の都市名と同じである可能性があります。
  5. 郵便番号は一意です

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

STATE
---
State ID (PK)
State Name

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

次に、論理的な質問が発生します。Zip IDを知っている場合、City IDを取得するにはどうすればよいですか?これに答えるには、ZipとCityの間のリンクを提供する必要があります。このリンクはどこに置くべきですか?ファクト#3から、都市にはさまざまな郵便番号が含まれる可能性があることがわかっているため、Cityテーブルには含まれていません。したがって、ZIPテーブルに含まれている必要があります。これは、ZIPテーブルの次のバージョンです。

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

ここで、ZipからCityに「移動」できるので、Cityテーブルについて説明します。都市名は他の人と同じ名前を持つことができます。したがって、それ(City Nameフィールド)を強制的に一意にする必要はありません。これがCityテーブルの最初のバージョンです:

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

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

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

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

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

ユーザー、チーム、キャピトルなどの別の問題について。まだ問題が発生していないため、今のところ何も言えません。

于 2010-08-31T14:41:31.383 に答える