2

私が取り組んでいるWebアプリケーションで、予期しない「バグ」が発生しました-アプリのデータベースには、「States」と「Cities」という2つのテーブルがあります(他にも多数あります)。

'状態'テーブルフィールド:

-------------------------------------------
idStates   |   State   |   Lat   |   Long
-------------------------------------------

' idStates 'は、自動インクリメントの主キーです。

'都市'テーブルフィールド:

----------------------------------------------------------
idAreaCode   |   idStates   |   City   |   Lat   |   Long
----------------------------------------------------------

' idAreaCode 'は、国コード+市外局番で構成される主キーです(たとえば、91422はインドの国コード、422はインドの都市の市外局番です)。' idStates 'は、' States 'テーブルから派生した外部キ​​ーであり、' Cities 'テーブル内の各都市を対応するStateに関連付けます。

国コードと市外局番の組み合わせは都市ごとに一意であるため、主キーとして安全に使用できると考えました。すべてが機能していました。しかし、インドのある場所では、データベース設計に予期しない「欠陥」が見つかりました。米国のように、インドは連邦民主主義であり、地理的に多くの州または連邦直轄領に分割されています。州と連邦直轄領の両方のデータが「」テーブルに保存されます。ただし、 2つの州(ハリヤーナ州パンジャブ州)に属し、それ自体が連邦直轄領でもある1つの場所(チャンディーガル)があります。

明らかに、現在のデータベース設計では、都市「チャンディーガル」の複数のレコードを保存することはできません。

提案された解決策の1つは、列' idAreaCode 'と' idStates 'を組み合わせた主キーを作成することです。

これが可能な最善の解決策であるかどうか知りたいですか?

(参考:InnoDBエンジンでMySQLを使用しています)。


詳しくは:

  • データベースには、各都市の気象情報が格納されています。したがって、州と市は各クエリの開始点です。
  • 各都市の最新データは、CSVファイルを使用して毎日挿入されます。CSVファイルには、各レコードを識別するために使用されるidStates(州の場合)およびidAreaCode(都市の場合)列が含まれています。
  • データベースの正規化は私たちにとって重要です。

注:都市テーブルに自動インクリメントの主キーを使用しない理由は、データベースがCSVファイル(別のアプリによって生成されたもの)を使用して毎日/毎時更新されるためです。また、CSVファイルの各レコードは、idStates列とidAreaCode列で識別されます。したがって、都市テーブルで使用される主キーは、テーブルが削除されて再度更新された場合でも、すべての都市で同じであることが望ましいです。郵便番号(またはPINコード)と市外局番(またはSTDコード)は、一意で静的(頻繁に変更しない)であるという基準を満たし、これらのリストを簡単に入手できます。(インドはPINコードを新しい形式に更新中であるため、今のところ市外局番を決定しました)。

私たちが決定した解決策は、データベース設計に変更を加えるのではなく、アプリケーションレベルでこれを処理することでした。データベースには、「チャンディーガル」のレコードを1つだけ保存します。このアプリケーションでは、検索をこのレコードにリダイレクトするために、「Chandigarh、Punjab」または「Chandigarh、Haryana」の検索用のフラグを作成しました。ええ、それは理想的ではありませんが、これが私たちがこれまでに遭遇した唯一の例外であるため、許容できる妥協案です。

4

8 に答える 8

4

電話帳のデータを収集しているようです。あなたは?なぜ州があなたにとって重要なのですか?この質問への答えは、おそらくどのデータベース設計があなたに最適であるかを決定するでしょう。

あなたは都市が何であるかは明らかだと思うかもしれません。そうではありません。それはあなたがデータで何をしようとしているのかによります。米国には、MSA(大都市統計地域)と呼ばれるこのユニットがあります。カンザスシティMSAは、カンザス州カンザスシティとミズーリ州カンザスシティの両方にまたがっています。MSAユニットが意味をなすかどうかは、データの使用目的によって異なります。米国の市外局番を使用して都市を決定した場合、MSAとは非常に異なるグループ化になります。繰り返しますが、それはあなたがデータで何をしようとしているのかに依存します。

一般に、政治的細分化の階層パターンが崩壊するときはいつでも、最も一般的な解決策は、多対多の関係を考慮することです。この問題は、他の多対多の問題を解決するのと同じ方法で解決します。2つの外部キーを使用して新しいテーブルを作成する。この場合、外部キーはIdAreacodeとIdStatesです。

これで、多くの州に1つの市外局番があり、多くの市外局番にまたがる1つの州を持つことができます。1つの例外だけをカバーするために、この余分なオーバーヘッドを受け入れるのは残念なことのようです。あなたが発見した例外が氷山の一角に過ぎないかどうか知っていますか、そしてそのような例外はたくさんありますか?

于 2009-08-12T11:57:00.090 に答える
2

参照するテーブルには主キーが持つすべての列が必要になるため、そのテーブルを参照する場合は、複合キーを使用すると問題が発生する可能性があります。

その場合は、シーケンスの主キーを使用し、idAreaCodeとidStatesをUNIQUENOTNULLグループで定義することをお勧めします。

于 2009-08-12T04:48:02.190 に答える
2

別のテーブル、国を追加するのが最善だと思います。あなたの問題は、データベースの正規化が重要である理由の例です。異なるキーを1つの列に単純に組み合わせて一致させることはできません。

したがって、これらのテーブルを作成することをお勧めします。

国:

+ ------------ + -------------- +
| country_id | country_name |
+ ------------ + -------------- +

状態:

+ ------------ + ---------- + ------------ +
| country_id | state_id | state_name |
+ ------------ + ---------- + ------------ +

都市

+ ------------ + ---------- + --------- + ----------- +
| country_id | state_id | city_id | city_name |
+ ------------ + ---------- + --------- + ----------- +

データ

+ ------------ + ---------- + --------- + --------- + ----- ----- +
| country_id | state_id | city_id | data_id | your_CSV |
+ ------------ + ---------- + --------- + --------- + ----- ----- +

太字のフィールドは主キーです。米国の場合は1、インドの場合は91などの標準的なcountry_idを入力します。city_idも標準IDを使用する必要があります。

そうすれば、最小限のオーバーヘッドで、互いに非常に高速に属するものを見つけることができます。その後、すべてのデータをデータテーブルに直接入力できるため、1つのエントリポイントとして機能し、すべてのデータを1つのスポットに保存できます。mysqlについてはわかりませんが、データベースがパーティション化をサポートしている場合は、country_idまたはcountry_id + state_idに従ってデータテーブルをいくつかのサーバーアレイにパーティション化できるため、データベースのパフォーマンスも大幅に向上します。1番目、2番目、および3番目のテーブルは、サーバーの負荷にほとんど影響を与えず、参照としてのみ機能します。主に4番目のデータテーブルで作業します。重複することなく、必要なだけデータを追加できます。

都市ごとにデータが1つしかない場合は、データテーブルを省略して、CSV_dataを次のように都市テーブルに移動できます。

都市

+ ------------ + ---------- + --------- + ----------- + --- ------- +
| country_id | state_id | city_id | city_name | CSV_data |
+ ------------ + ---------- + --------- + ----------- + --- ------- +
于 2010-07-10T17:29:36.423 に答える
1

特定の都市のレコードを追加できるようにキーに列を追加する場合は、データを適切に正規化していないことになります。都市が複数の州のメンバーになることができることを発見したので、Citiesテーブルから州への参照を削除してから、州を都市に関連付けることができるStateCityテーブルを追加することをお勧めします(am:mを作成します)関係)。

于 2009-08-12T05:19:55.383 に答える
1

代理キーを導入します。市外局番が番号を変更したり分割されたりした場合はどうしますか?ビジネスキーを主キーとして使用することは、ほとんどの場合間違いです。

上記の要約は、その理由のもう1つの例です。

于 2009-08-19T22:42:08.307 に答える
1

「国コードと市外局番の組み合わせは都市ごとに一意であるため、主キーとして安全に使用できると考えました。」

これを読んだ後、私はこのトピックでさらに何かを読むのをやめました。誰かがこのようにそれをどのように理解できますか?
定義によると、市外局番(インターネットで最初に見つけたもの):
-「市外局番は、北米番号計画に基づいて地理的地域を識別するために使用されるプレフィックス番号です。この3桁の番号は、任意の番号に割り当てることができます。カナダ、米国、メキシコ、ラテンアメリカ、カリブ海を含む北米で」[1]

変更可能で北米でのみ定義されていることを除けば、他の国では市外局番は3桁ではありません(一部の国では3桁では十分ではなく、数十万の場所があります。ところで、私の母の市外局番は5です。数字)およびそれらは固定された地理的位置に厳密にリンクされていません。

市外局番には、氷で漂う北極圏のキャンプ、遊牧民の部族、移動する軍隊、さらには大きな海洋船などの移動する場所があります。

次に、いくつかの都市を1つに(またはその逆に)マージするのはどうですか?

[1]
http://www.successfuloffice.com/articles/answering-service-glossary-area-code.htm

于 2010-11-11T18:06:00.950 に答える
0

単純に自動インクリメントされる新しい主キーフィールドをCitiesテーブルに追加することをお勧めします。KISSの方法論(シンプルに保つ)。

私の意見では、他の解決策は面倒で混乱を招きます。

于 2009-08-12T04:46:20.600 に答える
0
  1. データベースは正規化されていません。部分的に正規化されている可能性があります。その結果、拡張性にはさらに多くのバグと制限があります。

  2. 国、州、都市の階層で問題ありません。一部の人が示唆しているように、多対多の追加テーブルは必要ありません。この都市(そしてアメリカの多くの都市)は、3つの州で増殖しています。

  3. 連結されたCountryCodeとAreaCodeを単一の列に配置することで、すべてのアクセスに追加されたコードは言うまでもなく、基本的なデータベースルールに違反しました。さらに、CountryCodeは正規化されていません。

  4. 問題は、CountryCode+AreaCodeが都市のキーとして不適切な選択であるということです。実際には、それは都市とはほとんど関係がなく、広大な土地に適用されます。Cityの意味がtownに変更された場合(たとえば、会社が大きな町のデータの収集を開始した場合)、dbは完全に壊れます。

  5. マジシャンは、正解に近い唯一の答えを持っています。これは、正規化の欠如による現在の制限からあなたを救うでしょう。マジシャンの答えが正規化されていると言うのは正確ではありません。この場合、階層を形成する識別子の正しい選択です。ただし、「id」列は不要であり、100%冗長な列、100%冗長なインデックスであるため、削除します。char()列はそのままで問題ありませんが、PK(複合キー)には問題ありません。とにかくchar()列にインデックスが必要であり、一意であることを確認してください。

    • これ、リレーショナル構造、リレーショナル識別子があれば、問題は存在しません。
    • 貧しいユーザーは、ばかげたことを理解したり、意味のない識別子を追跡したりする必要はありません。それらは、当然、State.Name、City.Name、ReadingType、Data...を記述します。
  6. 階層の最下位(City)に到達すると、複合PKは面倒になり(3 x CHAR(20))、データテーブルに持ち込みたくありません(特に、毎日CSVインポートがある場合)。および都市ごとの多くの測定値または行)。したがって、Cityの場合のみ、PKとして代理キーを追加します。

  7. しかし、投稿されたDDLの場合、データベースを正規化せず、リレーショナル識別子を使用しない場合でも、そうです、CityのPKは正しくありません。(idStates、idAreaCode)である必要があり、その逆ではありません。それはあなたの問題を解決します。

ちなみに非常に悪いネーミング。

于 2010-11-10T12:26:06.453 に答える