web-dev-qa-db-ja.com

リレーショナルテーブルの命名規則

私は新しいプロジェクトを開始していますが、テーブル名と列名を最初から取得したいと考えています。たとえば、テーブル名には常に複数形を使用していますが、最近学習した単数形は正しいです。

したがって、テーブル「user」を取得し、ユーザーのみが所有する製品を取得した場合、テーブルの名前は「user_product」または単に「product」ですか?これは1対多の関係です。

さらに、(何らかの理由で)各製品に複数の製品説明がある場合、それは「user_product_description」または「product_description」または単に「description」でしょうか?もちろん、適切な外部キーが設定されている場合、ユーザーの説明やアカウントの説明などが含まれる可能性があるため、説明だけに名前を付けるのは問題です。

2列のみの純粋なリレーショナルテーブル(多対多)が必要な場合はどうなりますか? 「user_stuff」または「rel_user_stuff」のようなものですか?そして、もし最初のものであれば、これを例えば「user_product」と区別するものは何でしょうか?

どんな助けも大歓迎であり、皆さんがお勧めするある種の命名規則の標準がある場合は、遠慮なくリンクしてください。

ありがとう

134
Andreas

表•名前

最近学習した単数形は正しいです

はい。異教徒に注意してください。複数のテーブル名は、標準資料をまったく読んでおらず、データベース理論の知識がない人の確実な兆候です。

標準に関する素晴らしいことのいくつかは次のとおりです。

  • それらはすべて互いに統合されています
  • 彼らは一緒に働く
  • 彼らは私たちよりも大きな心で書かれたので、私たちはそれらを議論する必要はありません。

標準のテーブル名は、テーブル内の各rowを指します。これは、テーブルの内容全体ではなく、すべての表現で使用されます(Customerテーブルにはすべての顧客が含まれることがわかっています)。

関係、動詞フレーズ

モデル化された本物のリレーショナルデータベース(1970年以前のレコードファイリングシステム[便宜のためにSQLデータベースコンテナに実装される[Record IDsで特徴付けられる]とは対照的):

  • テーブルはデータベースのSubjectsであるため、名詞であり、これも単数形です
  • テーブル間の関係は、名詞間で発生するアクションです。したがって、それらは動詞です(つまり、任意の番号や名前は付けられていません)
  • is thePredicate
  • データモデルから直接読み取ることができるすべて(最後に私の例を参照)
  • (独立したテーブル(階層の最上位の親)の述語は、独立しているということです)
  • したがって、Verb Phraseは慎重に選択されるため、最も意味があり、一般的な用語は避けられます(経験があれば簡単になります)。動詞句は、モデルの解決に役立つため、モデリング中に重要です。関係の明確化、エラーの特定、テーブル名の修正。

Diagram_A

もちろん、リレーションシップはSQLで子テーブルのCONSTRAINT FOREIGN KEYとして実装されます(詳細は後述)。Verb Phrase(モデル内)、それが表すPredicate(モデルから読み取られる)、およびFK制約名

    Initiates
    Each Customer Initiates 0-to-n SalesOrders
    Customer_Initiates_SalesOrder_fk

表•言語

ただし、を説明する場合テーブルは、特に述語などの技術的な言語やその他のドキュメントでは、英語では自然に単数形と複数形を使用します。テーブルの名前は単一行(リレーション)に付けられ、言語は各派生行(派生リレーション)を参照することに注意してください。

    Each Customer initiates zero-to-many SalesOrders

じゃない

    Customers have zero-to-many SalesOrders 

つまり、テーブル「user」を取得し、ユーザーのみが所有する製品を取得した場合、テーブルの名前は「user-product」または単に「product」ですか?これは1対多の関係です。

(これは命名規則の質問ではなく、dbの設計の質問です。)user::productが1 :: nであるかどうかは関係ありません。重要なのは、productが個別のエンティティであるかどうか、およびIndependent Tableであるかどうかです。単独で存在できます。したがって、user_productではなく、productです。

そして、productuserのコンテキストにのみ存在する場合、つまりDependent Tableであるため、user_productです。

Diagram_B

さらに、(何らかの理由で)各製品に複数の製品説明がある場合、それは「user-product-description」または「product-description」または単に「description」でしょうか?外部キーを設定します。説明だけに名前を付けると、ユーザーの説明やアカウントの説明などを取得できるため、問題が発生します。

そのとおり。上記に基づいて、user_product_description xまたはproduct_descriptionのいずれかが正しいでしょう。他のxxxx_descriptionsと区別するためではありませんが、名前にそれが属する場所の意味を与えることであり、プレフィックスは親テーブルです。

2列のみの純粋なリレーショナルテーブル(多対多)が必要な場合、「user-stuff」または「rel-user-stuff」のようなものになりますか?そして最初の列が、たとえば「user-product」とこれを区別するものは何ですか?

  1. リレーショナルデータベースのすべてのテーブルが、純粋なリレーショナルの正規化されたテーブルであることが望まれます。名前でそれを識別する必要はありません(そうでなければ、すべてのテーブルはrel_somethingになります)。

  2. onlyが含まれる場合、2つの親のPK(論理レベルでエンティティとして存在しないlogical n :: n関係を解決して、physical table)、つまりAssociative Tableです。はい、通常、名前は2つの親テーブル名の組み合わせです。

    • そのような場合は、動詞句が親から親に適用され、子テーブルを無視して読み取られることに注意してください。これは、人生の唯一の目的が2つの親を関連付けることだからです。

      Diagram_C

    • not連想表(つまり、2つのPKに加えてデータが含まれる)である場合、適切な名前を付けると、関係の最後の親ではなく、動詞句が適用されます。

      Diagram_D

  3. 2つのuser_productテーブルで終わる場合、それはデータを正規化していない非常に大きな信号です。そのため、いくつかの手順に戻って実行し、テーブルに正確かつ一貫した名前を付けます。その後、名前は自動的に解決されます。

命名規則

どんな助けも高く評価されており、皆さんがお勧めする命名規則の標準がある場合は、お気軽にリンクしてください。

あなたがしていることは非常に重要であり、それはあらゆるレベルでの使いやすさと理解に影響します。そのため、最初から可能な限り多くの理解を得ることは良いことです。このほとんどの関連性は、SQLでコーディングを開始するまで明らかになりません。

  1. Caseは最初に対処する項目です。すべての上限は受け入れられません。特に、ユーザーがテーブルに直接アクセスできる場合は、大文字と小文字が混在しています。データモデルを参照してください。シーカーが小文字のみの認知されたNonSQLを使用している場合、それを与えることに注意してください。その場合、アンダースコアを含めます(例のとおり)。

  2. data focusを維持します。アプリケーションまたは使用目的ではありません。 2011年以降、1984年以来Open Architectureがあり、データベースはそれらを使用するアプリから独立しているはずです。

    そうすれば、それらが成長し、複数のアプリがそれらを使用しても、ネーミングは意味のあるままであり、修正する必要はありません。 (1つのアプリに完全に埋め込まれているデータベースはデータベースではありません。)データ要素に名前を付けるのはデータのみです。

  3. 非常に思慮深く、テーブルと列に非常に正確にと名前を付けます。 UpdatedDateデータ型の場合はDATETIMEを使用しないでください。UpdatedDtmを使用してください。投与量が含まれている場合は、_descriptionを使用しないでください。

  4. データベース全体でconsistentであることが重要です。製品の数を示すために1つの場所でNumProductを使用し、アイテムの数を示すために別の場所でItemNoまたはItemNumを使用しないでください。 number-ofにはNumSomethingを、識別子には一貫してSomethingNoまたはSomethingIdを使用します。

  5. 列名の前に、user_first_nameなどのテーブル名または短いコードを付けないでください。 SQLはすでに修飾子としてテーブル名を提供しています:

        table_name.column_name  -- notice the dot
    
  6. 例外:

    • 最初の例外はPKの場合です。PKは常に結合でコーディングし、データ列からキーを際立たせるために特別な処理が必要です。常にuser_idを使用し、idを使用しないでください。

      • これはnotプレフィックスとして使用されるテーブル名ですが、キーのコンポーネントの適切な説明的な名前であることに注意してください:user_ididuserではなく、ユーザーを識別する列ですテーブル。
        • (もちろん、ファイルが代理によってアクセスされ、関係キーがないレコードファイリングシステムを除き、それらはまったく同じものです)。
      • PKがFKとして運ばれる(移行される)場合は常に、キー列に正確に同じ名前を使用してください。
      • したがって、user_productテーブルには、PK user_idのコンポーネントとして(user_id, product_no)が含まれます。
      • これの関連性は、コーディングを開始すると明らかになります。まず、多くのテーブルでidを使用すると、SQLコーディングで簡単に混乱してしまいます。第二に、最初のコーダーが彼が何をしようとしていたのか分からない他の誰か。キー列が上記のように扱われる場合、どちらも簡単に防ぐことができます。
    • 2番目の例外は、同じ親テーブルtableを参照する複数のFKがあり、子で運ばれる場合です。 Relational Modelに従って、Role Namesを使用して、意味や使用法を区別します。 2つのAssemblyCodeに対してComponentCodeおよびPartCodes。そして、その場合、notを実行して、それらの1つに未分化のPartCodeを使用します。正確に。

      Diagram_E

  7. Prefix
    100以上のテーブルがある場合は、テーブル名の前にサブジェクトエリアを付けます:

    REF_参照テーブル用
    OE_注文入力クラスターなど。

    論理レベルではなく、物理レベルでのみです(モデルを乱雑にします)。

  8. サフィックス
    テーブルではサフィックスを使用しないでください。他のすべてでは常にサフィックスを使用してください。つまり、データベースの論理的な通常の使用では、アンダースコアはありません。ただし、管理側では、アンダースコアがセパレータとして使用されます。

    _Vビュー(もちろん、メインのTableNameが前面にあります)
    _fk外部キー(列名ではなく制約名)
    _cacキャッシュ
    _segセグメント
    _trトランザクション(ストアドプロシージャまたは関数)
    _fn関数(非トランザクション)など.

    形式は、テーブル名またはFK名、アンダースコア、アクション名、アンダースコア、最後にサフィックスです。

    サーバーからエラーメッセージが表示された場合、これは非常に重要です。

    ____blah blah blah error on object_name

    どのオブジェクトが違反され、どのオブジェクトが何をしようとしていたかを正確に知っています。

    ____blah blah blah error on Customer_Add_tr

  9. Foreign Keys(列ではなく制約)。 FKの最良の命名は、動詞句(「各」とカーディナリティーを除く)を使用することです。

    Customer_Initiates_SalesOrder_fk
    Part_Comprises_Component_fk
    Part_IsConsumedIn_Assembly_fk

    Parent_Child_fkではなくChild_Parent_fkシーケンスを使用する理由は、(a)探しているときに正しい並べ替え順序で表示され、(b)関係する子を常に知っているためです。は、どの親です。このエラーメッセージはすばらしいものです。

    ____Foreign key violation on Vendor_Offers_PartVendor_fk

    これは、動詞句が特定されているデータをモデル化することに煩わされている人に適しています。残り、レコードファイリングシステムなどでは、Parent_Child_fkを使用します。

  10. インデックスは特別であるため、順序で構成される独自の命名規則があり、各文字の位置は1から3です。

    U一意、または_一意でない場合
    Cクラスター化、または_非クラスター化の場合
    _セパレーター

    残りについて:

    • キーが1列またはごく少数の列の場合:
      ____ColumnNames

    • キーが数列を超える場合:
      ____PK主キー(モデルごと)
      ____AK[*n*]代替キー(IDEF1X用語)

    テーブル名は常にtable_name.index_name.として表示されるため、インデックス名にはnotが必要です。

    したがって、Customer.UC_CustomerIdまたはProduct.U__AKがエラーメッセージに表示される場合、意味のある何かを示します。テーブルのインデックスを見ると、簡単に区別できます。

  11. 資格のある専門家を見つけてフォローしてください。彼らのデザインを見て、彼らが使用する命名規則を注意深く研究してください。わからないことについて具体的な質問をしてください。逆に、命名規則や標準をほとんど考慮していない人からは、地獄のように実行してください。ここから始めましょう。

    • これらには、上記のすべての実際の例が含まれています。このスレッドで質問の名前を変更して質問します。
    • もちろん、モデルは命名規則を超えていくつかのother標準を実装しています。今のところそれらを無視するか、特定の新しい質問を自由に聞いてください。
    • それらはそれぞれ複数のページであり、Stack Overflowでのインライン画像サポートは鳥向けであり、異なるブラウザで一貫してロードされません。そのため、リンクをクリックする必要があります。
    • PDFファイルには完全なナビゲーションがあるため、青いガラスボタン、または展開が識別されているオブジェクトをクリックします。
    • リレーショナルモデリング標準に不慣れな読者は、 IDEF1X Notation が役立つと思うかもしれません。

注文入力と在庫 標準準拠アドレス

シンプルなオフィス間 Bulletin PHP/MyNonSQLのシステム

Sensor Monitoring 完全なTemporal機能付き

質問への回答

それはコメント欄で合理的に答えることができません。

ラリーラスティグ:
...最も些細な例でも...
顧客にゼロ対多の製品があり、製品に一対多のコンポーネントがあり、コンポーネントに一対多のサプライヤがあり、サプライヤがゼロ対多のコンポーネントを販売し、SalesRepに1つがある場合多対多の顧客顧客、製品、コンポーネント、およびサプライヤを保持するテーブルの「自然な」名前は何ですか?

コメントには2つの大きな問題があります。

  1. あなたはあなたの例を「最も些細な」と宣言しますが、それは何でもありません。この種の矛盾により、技術的に有能であるならば、あなたが本気かどうかはわかりません。

  2. その「些細な」推測には、いくつかの重大な正規化(DB設計)エラーがあります。

    • それらを修正するまで、それらは不自然で異常であり、意味をなさない。同様に、abnormal_1、abnormal_2などの名前を付けることもできます。

    • 何も提供しない「サプライヤ」がいます。循環参照(違法、および不要);購入の基礎として市販の商品(InvoiceやSalesOrderなど)を使用せずに製品を購入する顧客(または顧客は製品を「所有」していますか?)未解決の多対多の関係。等.

    • それが正規化され、必要なテーブルが識別されると、その名前が明らかになります。当然。

いずれにせよ、私はあなたのクエリを処理しようとします。つまり、あなたが何を意味しているかわからないので、私はそれにいくらかの感覚を追加する必要があることを意味します。総誤差はリストするには多すぎるため、スペアの仕様を考えると、すべてを修正したとは確信できません。

  • 製品がコンポーネントで構成されている場合、製品はアセンブリであり、コンポーネントは複数のアセンブリで使用されると想定します。

  • さらに、「サプライヤはゼロから多数のコンポーネントを販売する」ため、not_製品またはアセンブリを販売するため、コンポーネントのみを販売します。

投機vs正規化モデル

気付いていない場合は、角の角(独立)と角の丸(依存)の違いが重要です。IDEF1X表記リンクを参照してください。同様に、実線(識別)対破線(非識別)。

...顧客、製品、コンポーネント、およびサプライヤを保持するテーブルの「自然な」名前は何ですか?

  • お客様
  • 製品
  • コンポーネント(または、1つの事実が他の事実を識別することに気付く人のためのAssemblyComponent)
  • サプライヤー

テーブルを解決したので、あなたの問題を理解できません。おそらくspecific質問を投稿できます。

VoteCoffee:
Ronnisが2つのテーブル(user_likes_product、user_bought_product)の間に複数のリレーションシップが存在する彼の例で投稿されたシナリオをどのように処理しますか?私は誤解するかもしれませんが、これはあなたが詳述した規則を使用して重複したテーブル名をもたらすようです。

正規化エラーがないと仮定すると、User likes Productはテーブルではなく述語です。それらを混同しないでください。主題、動詞、述語に関連する私の答えと、すぐ上のラリーへの私の応答を参照してください。

  • 各テーブルには、setのファクトが含まれています(各行はファクトです)。述語(または命題)は事実ではなく、真実である場合とそうでない場合があります。

    • リレーショナルモデルは、1次述語計算(より一般的には1次論理)に基づいています。述語は、単純で正確な英語の単一句の文であり、trueまたはfalseに評価されます。

    • さらに、各テーブルは、1つではなくmanyPredicatesを表すか、その実装です。

  • クエリは、true(ファクトが存在する)またはfalse(ファクトが存在しない)になるような述語(または、連鎖された複数の述語)のテストです。

  • したがって、テーブルの名前は、私の回答(命名規則)で詳述されているように、行、ファクト、および述語について文書化する必要があります(必ず、データベース文書の一部です)が、述語の個別のリストとして。

  • これは、それらが重要ではないという提案ではありません。それらは非常に重要ですが、ここでは書きません。

  • すぐに。 Relational ModelはFOPCに基づいているため、データベース全体はFOPC宣言のセット、つまり述語のセットであると言えます。しかし、(a)述語には多くのタイプがあり、(b)テーブルは1つの述語を表さない(many述語の物理的な実装であり、異なるtypes述語の)。

  • したがって、「the」というテーブルの名前を「表す」という述語は不条理な概念です。

  • 「理論家」は少数の述語のみを知っており、RMがFOLに基づいているため、データベース全体が述語のセットであり、異なるタイプであることを理解していません。

    • そしてもちろん、彼らは彼らが知っている少数から不条理なものを選択します:EXISTING_PERSON; PERSON_IS_CALLED。そんなに悲しくなければ、それは陽気でしょう。

    • また、標準またはアトミックテーブル名(行に名前を付ける)は、すべての冗長性(テーブルにアタッチされたすべての述語を含む)で見事に機能することに注意してください。逆に、ばかげた「テーブルは述語を表す」名前はできません。これは、述語についてほとんど理解していないが、それ以外のことを遅らせている「理論家」にとっては問題ありません。

  • データモデルに関連する述語は、モデルのinで表され、2つの順序になります。

    1. 単項述語
      最初のセットはdiagrammaticであり、テキストではありません:記法自体。これらには、さまざまな存在が含まれます。制約指向;および記述子(属性)述部。

      • もちろん、それは、標準データモデルを「読み取る」ことができる人だけがそれらの述語を読むことができることを意味します。そのため、テキストのみの考え方にひどく不自由な「理論家」はデータモデルを読むことができず、1984年以前のテキストのみの考え方に固執するのです。
    2. Binary Predicate
      2番目のセットは、ファクト間でrelationshipsを形成するセットです。これが関係線です。動詞句(上記で詳述)は、実装された述語であるpropositionを識別します(クエリを介してテストできます)。それ以上明示することはできません。

      • そのため、標準データモデルに堪能な人には、すべての述語関連するがモデルに文書化されます。述部の個別のリストは必要ありません(ただし、データモデルからすべてを「読み取る」ことができないユーザーは必要です!)。
  • ここに Data Model があります。ここに述語をリストしました。実例などの述語、および関係のものを示しているため、この例を選択しました。リストされていない述語は記述子のみです。ここでは、シーカーの学習レベルのために、私は彼をユーザーとして扱っています。

したがって、2つの親テーブル間の複数の子テーブルのイベントは問題ではありません。ExistentialFactがコンテンツを表すように名前を付け、名前を正規化します。

連想表の関係名に動詞句に指定したルールがここで有効になります。ここに Predicate vs Table の議論があり、まとめて言及されたすべてのポイントをカバーしています。

述語の適切な使用とその使用方法(ここでのコメントへの応答とはまったく異なるコンテキスト)についての簡単な説明については、 this answer にアクセスしてください。 =、およびPredicateセクションまで下にスクロールします。


チャールズバーンズ:
シーケンスでは、Oracleスタイルのオブジェクトが、あるルール(例:「add 1」)に従って番号とその次の番号を格納するために純粋に使用されることを意味しました。 Oracleには自動IDテーブルがないため、私の一般的な用途はテーブルPKの一意のIDを生成することです。 INSERT INTO foo(id、somedata)VALUES(foo_s.nextval、 "data" ...)

わかりました。これがKeyまたはNextKeyテーブルと呼ばれるものです。そのような名前を付けてください。 SubjectAreasがある場合は、COM_NextKeyを使用して、データベース全体で共通であることを示します。

ところで、それはキーを生成する非常に貧弱な方法です。まったくスケーラブルではありませんが、Oracleのパフォーマンスがあれば、おそらく「正常」です。さらに、データベースが代理領域でいっぱいであり、それらの領域では関係がないことを示しています。これは、非常に低いパフォーマンスと整合性の欠如を意味します。

335
PerformanceDBA

単数形と複数形について「正しい」ことはありません-それはほとんど好みの問題です。

それはあなたの焦点に一部依存します。テーブルをユニットと考えると、「複数」を保持します(複数の行を保持するため、複数名が適切です)。テーブル名がテーブル内の行を識別するものと考える場合、「単数形」をお勧めします。これは、SQLがテーブルの1つの行で動作していると見なされることを意味します。それは大丈夫ですが、通常は単純化しすぎです。 SQLはセットで動作します(多かれ少なかれ)。ただし、この質問への回答については単数形で対応できます。

  1. おそらくテーブル「user」、別の「product」、およびユーザーを製品に接続するための3番目のテーブルが必要になるため、テーブル「user_product」が必要です。

  2. 説明は製品に適用されるため、「product_description」を使用します。各ユーザーが各製品に名前を付けていない限り...

  3. 「user_product」テーブルは、製品IDとユーザーIDを含むテーブルの例であり(他のことはほとんどありません)。 2つの属性テーブルに同じ一般的な方法で名前を付けます: 'user_stuff'。 'rel_'のような装飾的な接頭辞は実際には役に立ちません。たとえば、各テーブル名の前に「t_」を使用している人がいます。それは多くの助けではありません。

16

Singular vs. Plural:1つを選んでそれを使い続けます。

列に接頭辞/接尾辞/接尾辞を付けたり、とにかく列であるという事実を参照して固定したりしないでください。テーブルについても同じことが言えます。テーブルにEMPLOYEE_TまたはTBL_EMPLOYEESという名前を付けないでください。2番目のビューがビューに置き換えられるため、混乱を招きます。

Varcharの「vc_firstname」や「flavour_enum」など、名前にタイプ情報を埋め込まないでください。また、列名に「department_fk」や「employee_pk」などの制約を埋め込まないでください。

実際、私が考えることができる* fixesの唯一の良いところは、where_ttbl_orderuser_vwのような予約語を使用できることです。もちろん、これらの例では、複数形を使用すると問題が解決します:)

すべてのキーに「ID」という名前を付けないでください。同じものを参照するキーは、すべてのテーブルで同じ名前を持つ必要があります。ユーザーID列は、ユーザーテーブルおよびユーザーを参照するすべてのテーブルでUSER_IDと呼ばれます。名前が変更されるのは、Message(sender_user_id、receiver_user_id)など、異なるユーザーが異なる役割を果たしている場合のみです。これは、大規模なクエリを処理するときに非常に役立ちます。

CaSeについて:

thisiswhatithinkofalllowercapscolumnnames.

ALLUPPERCAPSISNOTBETTERBECAUSEITFEELSLIKESOMEONEISSCREAMINGATME.

CamelCaseIsMarginallyBetterButItStillTakesTimeToParse.    

i_recommend_sticking_with_lower_case_and_underscore

一般に、参照されるテーブルの名前よりも、それが記述するリレーションと一致するように「マッピングテーブル」という名前を付ける方が適切です。ユーザーは、user_likes_productuser_bought_productuser_wants_to_buy_productなど、製品との関係をいくつでも持つことができます。

16
Ronnis

複数形は一貫して使用されている限り悪くありませんが、単数形が私の好みです。

多対多の関係の概要を説明する場合を除き、アンダースコアは不要です。また、ORM内の物事を区別するのに役立つため、最初の大文字を使用します。

ただし、多くの命名規則があるため、アンダースコアを使用する場合は、一貫して行われていれば問題ありません。

そう:

User

UserProduct (it is a users products after all)

1人のユーザーのみが製品を所有できる場合

UserProductDescription

ただし、製品がユーザーによって共有されている場合:

ProductDescription

多対多の関係のためにアンダースコアを保存すると、次のようなことができます:

UserProduct_Stuff

userProductとStuffの間でM-to-Mを形成する-質問から、必要な多対多の正確な性質がわからない。

4
amelvin

複数形よりも単数形を使用する方が正確ではありませんが、どこで聞いたことがありますか?むしろ、データベーステーブルの命名には複数形がより一般的であると言いたいのですが、私の意見では、より論理的です。ほとんどの場合、テーブルには複数の行が含まれます;)概念モデルでは、エンティティの名前は単数形であることがよくあります。

あなたの質問について、「Product」と「ProductDescription」がモデルのアイデンティティ(つまりエンティティ)の概念である場合、単に「Products」と「ProductDescriptions」というテーブルを呼び出します。多対多の関係を実装するために使用されるテーブルの場合、「Student2Course」などの命名規則「SideA2SideB」を使用することがほとんどです。

2
Ozzy