sql >> データベース >  >> RDS >> Mysql

掲示板-データベースの最適化

    パートI

    改訂09Dec10 01:00 EST

    あなたのDDLを見ました。 Ok。最初に一歩下がってデータベースを整理する必要があります。これで問題の半分が解決されます(SQLは単純で、高速で、インデックスが少なく、一時テーブルは必要ありません)。しばらくの間、ああ、あなたはあなたのコラムを持っていると思いました、それは安定しているに違いありません、しかしチャンスはありません。最初からトップダウン、わかりました。このエンティティ関係図を見てください(エンティティ、関係および属性であるデータモデルでの作業は無駄です 、ERが正しくなるまで)、それが正しいことを確認します。

    • そのための方法は、次の質問に答えることです(短い答えで構いません)。これらの質問は、エンティティとビジネスルールを明確にしています。 。データベース全般、特にデータをどのように理解するかが重要です。あなたは自分で長い道のりを歩んできたので、そこからそれを取ることができます。

    • ▶この投稿◀ 従うべき正式な段階を理解するために、あなたに役立つかもしれません。ここで短絡しています。

    • 最も重要なのは、完全に、そして完全に、関数とコーディング要件を忘れることです。データは、単にデータとして、アプリケーションから独立してモデル化する必要があります。機能モデリングは別の科学です。まず1つ正しくします。次に、もう一方を正しくします。そして2人は一緒に美しい曲を演奏します。それらを一緒に妨害してみてください。両方のタスクを同時に実行すると、郊外のガレージバンドを作ることすらできません。

    簡潔にするために、そしてこれを読む人のために、私は閉じたセクションと開いたセクションを使用します。開いているアイテム(ディスカッション)が閉じられたら、簡潔にして、閉じているセクションに移動します。物事が時々私たちを悩ませるために戻ってくるので、番号付けを維持してください。同じことをしたい場合もあれば、自分の側のディスカッションを削除したい場合もあります。

    きれいな写真へのリンクは最後にあります。

    お詫び:編集は機能しません。サブナンバリングに一貫性がありません

    解決済みの問題

    1. users.bb_locations_csvは、ユーザーと場所の間の多対多の関係です。
      • これらの各要素は、個別の行の個別の列のエントリである必要があります
      • 1人のユーザーが多くの場所を持つことができます 1つの場所に多くのユーザーを含めることができるのは多対多です
      • ▶この投稿◀を読む それがどのように扱われ、どの段階で扱われるかについての議論のために
      • この論理ステージでは、これは単なるn ::n関係です。私が描いたように、今のところそれを忘れることができます。物理ステージに到達すると、単純に提供されます。
      • 信頼してください。...WHEREIN()よりも複雑でないコードを提供します。 宣言された目的のために。
      • 考え直してみると、指を折ると入力がさらに遅くなるので、やめたほうがいいです
      • わかりました。アプリはブラウザベースで、ページは動的です(私のアドバイスは、修正が必要な静的ページに関するものでした)。チェックボックスをオンにしてください。
    2. users.bb_categories_csvは、ユーザーとカテゴリ間の多対多の関係です
      • 同上。
    3. 確認済み:セキュリティ情報(bbs)はユーザーなしでは存在しません。ユーザーが掲示板を発行すると、サイクル全体が開始されます。次に、返信と評価を招待します。

      3.1確認済み:掲示板は実際には1つしかなく、データベースにThingとして存在していません。

      3.2確認済み:組織に複数の掲示板が存在することはなく、分類と分類はすべてカテゴリテーブル/機能によって適切に処理されます

    4. 削除されました。

    5. 確認済み:掲示板と返信の違いは、返信は掲示板の存在に依存しており、タイトルがなく、掲示板自体に依存しているため、場所やカテゴリで分類されていないことです。

    6. 削除されました。

    7. コメントが記載されています。解決しました。

    7.1。別のユーザーが送信した1つの掲示板ごとに、各ユーザーは複数の返信を投稿できます。

    7.2。ユーザーが送信した1つの掲示板ごとに、そのユーザーは1つまたは複数の返信を投稿できます。

    7.3。削除されました。

    7.4。削除されました。


    8。確認済み:各ユーザーは、最大で1つの評価を掲示板に投稿できます(取り消し/変更可能)

    9。確認済み:各ユーザーは、返信に対して最大1つの評価を投稿できます(同上)

    10.1。指定: usernameは組織に由来し、従業員を識別する一意の名前です。たとえば、メールは[email protected] です。 -認証はLDAPを使用して行われ、これは従業員に関する他の情報を取得するために接続するために必要です。

    • 確認済み:UserNameは優れた識別子です

    10.2。確認済み:FirstName、LastName ... BirthPlaceなどは、 People を確保するための(従来の)列のままです。 複製されません。

    11。与えられたもの:現在、私たちは約3つの本社と多くのフィールドオフィスしかないため、組織内で一般的に知られているカジュアルな名前でオフィスを識別できます。したがって、例としては、ワシントンDCまたはバージニアフィールドオフィスがあります。合計で20未満に抑えるように努めると思います。ユーザーに対してオフィスを一意に識別するために使用できるため、各場所の正確な住所も記録したいと思います。

    • 提供: StateCode + Town PKとして; IsMainOffice ブール値として。


    12。確認済み:説明 およびName カテゴリの場合 必須です。

    13。与えられた:ユーザーはいくつかのカテゴリーに投稿することができなくなります。十分に高い権限を持つユーザーのみが、特定のカテゴリに投稿する権利を持ちます。

    • 提供:許可 ユーザー、場所、カテゴリ そのような権利を評価する方法です。


    14。確認済み: Location.Administrator UserIdです Locationの管理者 。

    15。与えられたもの:好きか嫌いかだけが必要になるでしょう。投票しないのと同じなので、中立的な立場である必要はないと思いますか?好きなことは、正直に投稿する速報の返信に関連しているようです。つまり、私はあなたの反応を見て、私自身を書く代わりに私はあなたに同意します-既存の掲示板は組織の社会的側面のいくらかであり、好きと嫌い/同意と反対は参加を奨励するレベルの論争を生み出すと思います。ただし、掲示板が好きまたは嫌いな場合は、必ずしも完全に適切であるとは限りません。

    15.1提供: Like BulletinRatingのブール値として およびResponseRating 。これには、すべてのアクセスで解釈が必要になります。
    15.2。ブール値でなくなったら、 RatingCodeに変更できます。 、およびルックアップテーブルとして実装されます。次に、名前は結合によって決定され、解釈は排除されます。これをFirstDataModelで描いたので、私が何を意味するのかがわかります15.3。 2番目のデータモデルで削除されました。

    16。確認済み:各ユーザーには自宅の場所があります (場所のリスト以外

    17。確認済み:許可 (13)による。

    18。確認済み:データモデルに従って、さらにアクセス許可が必要になる場合があります。

    18.1。今これを行うと、組織が特定の Personを阻止することを決定したときに心配する必要がなくなります。 Responsesの投稿から またはBulletins 、またはそれらを評価します。昨日その機能を実装したいと考えています。

    18.2。実装しない場合でも、実装する値の間にギャップを残してください。

    19確認済み: Bulletin です 場所

    19.1。確認済み: Bulletinsはありません Locationなし

    19.2。確認済み: Bulletinsはありません Locationなし 。

    19.3確認済み: Bulletinsはありません ユーザーなし (宣言型)。しかし、これまでのところ、その Userを制約する方法はありません。;したがって、すべての User Bulletinを挿入できます Locationの場合 (たとえば、 Locationsなどのコードで制約することができます 各ユーザーが興味を持っている

    19.4確認済み: BulletinRatingsはありません Bulletinなし と評価ユーザー

    19.5確認済み: Responsesはありません Bulletinなし 。

    19.4確認済み: ResponseRatingsはありません Responseなし と評価ユーザー

    19.7。ただし、ユーザーが存在する可能性があります 、Locations 、および カテゴリ`、独立して。


    20。よろしければ、命名規則などを提供します。これらは自明である必要があり、SQLのコーディングを開始したときにのみ値が表示されます。そうでない場合は、お問い合わせください。手始めに、すべての名前は単数形です。大文字と小文字が混在していると読みやすくなります(SQL言語には大文字を使用することになっています)。

    20.1。私の経験では、tableNameとは対照的にtable_nameは実際には技術的な形式であり、ユーザーはそれらを好きではありません。一貫した混合ケースは誰もが好きです。変更することは不可能なことの1つなので、慎重に選択してください。

    21。テーブルをグループ化する必要がある場合は、これは物理的な問題であることに注意してください。論理データモデルレベルでは、テーブルには通常の名前が付けられており、物理的な問題によって整理されています。物理テーブルの前に次のようなものが付いていると想像してください(これには大文字を使用してください):
    - REF _ 参照用(ユーザーなど)およびルックアップテーブル
    - BUL _ Bulletinシステムの場合

    テーブルに大文字で名前を付けることができませんか?理由はわかりません。なぜ大文字のテーブル名を使用できないのかわかりません。 MyIsamデータベーステーブルの使用と関係がありますか?


    22。 ランク (すべて)データベースから直接導出できます(データモデリング中のコードについて心配する必要はありません)。保存すると、正規化エラーになります。重複した列。これは最新の状態に保つ必要があります。派生値と同期しなくなる可能性があります。これは更新異常と呼ばれます。 5番目の通常の形式は、更新の異常を排除します。これが私の最小レベルの正規化なので、それが私から得られるものです。

    22.1。並べ替え順序や人気の問題にはまったく干渉していません。実際、その音によって、あなたはその機能を閉じていません。冗長なデータ、ランクのみを取得しています 、出力、正規化プロセスの一部として。

    22.2。これが▶クイックチュートリアル◀ RANK()演算子で(一般的に知られているように)。これはANSISQLではありません。これは、OracleおよびMSの拡張機能です。ただし、サブクエリを理解している場合は必須ではありません。そのため、Sybaseにはサブクエリがありません。 MySQLにそれがあるとは思えないので、頭を悩ませる必要があります。スカラーサブクエリを理解することが前提条件です。 Sybaseの構文なので、セミコロンなどを追加してください。具体的な質問をしてください。

    Rank =(SELECT。。。。。。ランクとして(SELECT ...)と同じですか?


    22.3。理由を理解する必要があるので、まったく問題ありません。やみくもに単純なルールに従うのは子供だけであり、あなたは確かにその一人ではありません。

    23。確認済み: users.total_bulletins 冗長です。それを導き出すことができます。削除されました。

    24。すべてのPKはIDです。コードで迷子になるのにもう飽きていませんか? Idを貼り付けることを忘れてください 動くすべてのもののIoTPK、あなたのユーザーがどのようになっているのかを調べましょう エンティティを特定します。どのエンティティが本当に独立しているか、他のエンティティは独立したエンティティに依存しています。

    24.1。 Idは絶対に使用しないでください またはそのような形式。 PKの場合は、完全なフォームを使用してください。

    24.2。 PKテーブルを含め、どこにいてもlocation_id、location_idを呼び出します。例外は、役割を表示する必要がある場合です。これはデータモデルで明らかになります。

    25。宣言型の参照整合性、定義済みはありません 外部キー。それは多くの異なる理由で悪いニュースです。これらの質問が明確になったら、それらを追加してください。DRIは、すべてではないにしても、可能な限り、SQLで整合性が宣言されることを意味します。 ISO / IEC / ANSI SQL標準はこれを可能にしますが、市場のフリーウェア側は標準を提供しておらず、ゆっくりと追いついてきています。これは、PKが親テーブルに存在しない限り、サーバーがFKテーブルの行の追加を許可しないことを意味します。 MySQLは最近、外部キーにDRIを提供しました。 FKについては、▶を参照してください。この記事◀

    25.1。 CHECK制約とルールについては、コードで実装する必要があります。

    私の外部キーは、users-id(fk)=users.id(pk)のようなものです。私が行ったこと以外にそれらを追加する方法はわかりませんが、方法がわかれば確実に追加します。

    25。 コメントに注意してください。 私はMySQLのスペシャリストではありません。はい、それらはあなたがあなた自身のために理解しなければならない問題です。一般的に、私の熟読から、MySQLは無意味です。 SQLのようなものには、InnoDBが必要です。


    27。与えられた:私は会報の分類要件を再考しました。ユーザーは時系列で簡単に並べ替えることができ、理にかなっています。ユーザーは、掲示板への最新の返信の日付で掲示板を並べ替えることができます。そうすれば、ランクを忘れることができ、最後の応答時までに時系列で掲示板を並べ替えるのは本当に簡単なはずです。あなたの考えは何ですか。

    未解決の問題

    (なし)

    データモデル

    わかりました。ERDに問題がなく、すべてのクローズドイシューを実装していると仮定して、データをモデル化し、5番目のデータモデル09Dec 10 を準備しました。 あなたのレビューのために。間違いなくもっと必要です これに関するフィードバック、質問など。私はそれが行われたことを受け入れるのに苦労しています。おそらく、問題のある領域の実際のコードを書き始めるのが最善でしょう。

    リンク

    ▶IDEF1X表記へのリンク◀ データモデルを読む前に、これを読んで理解する必要があります。

    ▶第5速報データへのリンクモデル◀ 実体関連図 最初のページにあり、その後にデータモデルが続きます 。

    • キーはほとんどストレートなIDEF1Xです(対位法として提供したUserIdを除く)。これは、財布のリレーショナルキーを意味します。強化されておらず、物理的な考慮事項に最適化されていません。あなたがそれらを嘲笑する前に、最初にそれらに気づき、それらを登録し、そしてそれらを評価してください。もちろん、追加することもできます Id IoTキーですが、その前に、何が失われるのかを理解していることを確認しましょう。

    • 表記法のドキュメントにある識別子(実線)に注意してください。システムの脊椎、椎骨は Location ... Bulletin ... Responseです。 。

    • キーは実際に多くのビジネスルールを実装していることに注意してください。

    • 私がレンダリングした自然階層に注目してください。何か意味があるかどうかを確認してください。

    • VerbPhrasesは本当に重要です。それらが何かを意味するかどうかを確認してください。

    最初のデータモデルと応答に関するコメント

    私が持っている質問の1つは、場所の主キーが子の主キーを形成するために使用されるということです(実線で結ばれています)その概念を本当に理解していません

    • Bulletinの適切な識別子は何ですか? 、ユーザーが掲示板を特定するために自然に使用するもの...
    • 「昨日バージニアFOからの速報を見たことがありますか?」、
    • 「ワシントンのサリーは確かに良い速報を書いています」など

    または、なぜその関係がユーザーと掲示板の間に存在しないのですか?

    • 上記の意図に従って、評価を表として示し、レンダリングがどのようになるかを示したので、一度削除します

    • パーミッションはエンティティである必要があると思います。

    • Bulletin PKは(StateCode、Town、UserId、SequenceNo)になりました 。明確にするために、 SequenceNo StateCode、Town、UserId内にあります :SallyのMO /BillngsFOに関する5番目の速報では5になります。

    • ユーザー設定BulletinsPerPageに注意してください などは、 Userと1:1です。 、したがって、 Userにあります;子テーブルは正しくありません。

    • 誤植が修正されました。

    2番目のデータモデルと応答に関するコメント

    • 両方のBulletinのPK およびResponse (7)を反映するように変更されました。 BulletinNo およびResponseNo BulletinDateに置き換えられました およびResponseDate (以前は CreatedDate でした )、 Userごとに複数の返信を許可するため Bulletinごと 。

    第3のデータモデルと応答に関するコメント

    良い休憩があったと信じてください。

    1. 少なくとも30年前(私が知っていることですが)、業界の巨人はこの議論をしました。名前は常に単数形です。テーブルは名詞です。 VerbPhrasesは動詞です。これは、dbの命名規則に限定されず、ドキュメント、論文、論文などに適用されます。ドキュメントの最後に5つの結論がありますが、目次とページの上部の両方にセクションまたは章のタイトルがあります。は「結論」です。

      ユニでずっと戦った後、最初の有料プログラミングの仕事を始めて、大学での理論的な議論とは対照的に、現実の世界でのルールの重要性を見てすぐに、私はそれを無駄としてあきらめました時間の。その間ずっと、私が無駄にした時間とエネルギーは、生産的な仕事をするために解放されました。それ以来、私は巨人に質問しません。私はただ受け入れます。彼らの心が私のものよりも大きいこと。それは、基準を受け入れること、法の範囲内で行動すること、または神のようなものです。違法なことをする理由は本当にありません。

      とにかく、そのようなルールによってサポートされている言語化の容易さ(ディスカッション、SQL、ドキュメント)は十分に説明できません。 SQLコードをどんどん書くと、それが明らかになります。

      いつでも自由に使用できます。単数形のみをお届けします。

    2. 私は元気です。

      ただし、特定されたシーケンス内のこれら2つの要素(非PK一意インデックスまたは代替キー)は、個人の一意性を確立するために普遍的に必要であることに注意する必要があります。それらを削除すると、2つの結果になります。まず、ユーザー全体で一意性を識別できなくなります (したがって、行が重複している可能性があります)。次に、AKは一意ではなく、反転エントリになります。

    3. 重要なのは(投稿の1つとは異なり)、 Userと1対1の列です。 PK、 Userに常駐する必要があります 。すべての設定。 InterestedLocationsをクリーンアップしたので およびInterestedCategories 、私は BulletinsPerPageしか知りません 残り;でも他にもあると思います。 IsPreference2 例です。ブール値の;NumPreference3 例です。整数の。など。実際の設定とは何かを教えてください。

      (複数形で試してみましょう:... Usersで1::1の列 PK、ユーザーに常駐する必要があります 。ただ私のためにそれをしません、私は壊れた英語に夢中になります、そして私は私の母国語について少し貴重です。)

      データモデルが更新されました。

    4. 素晴らしい。よろしければお知らせください。物理モデルをお渡しします。

      VerbPhrasesはどうですか?

    コメントre06Dec 10 20:38 EST(小さな更新)


    28。もちろん、FKとしてPKが1つしか出現しない場合、FK列名はPK列名と同じです。ただし、FKが複数ある場合( ResponseRating をご覧ください) )、3つの UserIds があります )、それらを区別する必要があります。 IDEF1Xの用語では、これはロールと呼ばれます。 ユーザーの役割 Bulletinを発行した人 Issuerです 、 等々。明らかに、その名前を使用し、階層全体で一貫性を保つことをお勧めします( UserId ではありません)。 Bulletin 次に、 Responseに到達したとき 、2つあり、差別化が必要な場合は、 IssuerIdに変更します。 。私はあなたがそれに問題があるかもしれないと思った。初期の使用法はIssuer.UserIdです。 UserIdであることが完全に明確になるようにします FKとして、役割は Issuer ;物理モデルに到達すると、 IssuerIdに簡略化されます。 。

    同様に、多くのDateTime列(必要に応じてDate、それ以外の場合はDtm)があり、区別する必要があります。

    29。 IDEF1X表記のドキュメントは意味がありませんでしたか?

    • 各テーブルのPKは、指定された順序で境界線より上にあります。
    • とにかく親テーブルのPKを保持していることを忘れないでください。意味がある場合は、それらのFKを使用して子PKを形成します。
    • Bulletinの場合 :

      • 場所FK(StateCode、Town) 発行対象
      • UserId 発行者の
      • 一意にするために発行されたDateTime。
      • したがって(StateCode、Town、IssuerId、BulletinDate) `
    • すべてのResponseRatingsを削除するには このBulletin WHERE =を使用します これらの4つのBulletin 列。


    30。 (State、Town) LocationのPKです 、どこにでも運ぶ。そして、それは Bulletinの一部を形成します PK、つまり、依存テーブルは Bulletin を保持しているため、これらの列を伝達します。 PK。

    以前、(State、Town)を特定しました PKです。そのままにしておきます 変更については(38)を参照してください。


    33。議論する価値があります。はい、(例) Responsesを表示するときに表示する場合 、およびユーザーは UserNameを理解しています 。いいえ、30バイトで、一意の4バイトの UserIdもある場合 。アイデアは、6列の30バイトのキーが面倒すぎて子に移行できないと最終的に判断したときに、何を諦めているのかを認識して、これらの選択を意識的に行うことです。

    • 最初に述べたので、 UserIdを使用します 典型的なIdとして Pk、複数の子テーブルに運ばれる/移行されるため。
    • それがどのように作成されたかは後で使用できます。しかし、それは純粋な代理PKです。


    34。問題ない。 カテゴリ すでに持っています。 Orderを変更します ListOrderへ 。


    35。もちろん。私が読んだり聞いたりしたことに基づいて、私はそれに非常に満足しています。しかし、コードを書く前に、ある程度の自信を得るには、何度も行ったり来たりしたいと思います。または、それを学習体験と見なし、モデルとコードが後で変更される可能性があることを受け入れます。今すぐフィジカルを制作しますか?訂正をいただければ、次のバージョンを公開します。 Userの設定を期待しています 。また、関数をすばやく実行し、必要な列がすべて揃っていることを確認します。

    学習と興味のために、他の答えのいくつかを見てください。


    36。参加します。 fourに参加するだけです 1つではなく3つの列。 SQLは結合で面倒であり、それを簡単にするはずだった新しい構文は実際にはもっと面倒です。私のコーダーは結合を作成しません。時間とタイプミスを節約します。 2つ以上のテーブルを指定し、すべての列と結合を含むコードを生成するprocがあります。私はあなたのためにそれを変換するのに十分なMySQLを知りません。

    データモデルが更新されました。

    コメントre08Dec 10 20:49、4番目のデータモデルと応答


    すぐ上の前のセクションを確認してください。小さな更新があります。

    IDEF1X:あなたの速度は素晴らしいです。

    常に子供に注意してください 親PKをFK(実線または破線)として「継承」します。それ以外の場合、それらの間に関係はありません。とにかく子に存在するこれらの列を使用して、子PKを形成することにより、意味を実行します。 (そしてそれは固体と壊れたものの違いです)。したがって、子の独立した識別子を探す必要はありません。この方法の関係力は、後でコーディングするときに明らかになります。

    私たちが扱っているセクションは、識別子についてです。 :ナチュラルvsユーナチュラル;意味のあるvs意味のない。後で、子PKが親PKから形成されるときに、エンジンのリレーショナル機能をどのように使用できるかを確認します。 (あなたの名前はあなたの父親の名前と同じではありませんか?)

    リレーショナルデータベースとその機能を理解することも重要です。これは、OOの観点からデータベース(たとえば)にアプローチし、クラスを「永続的」にする場所として扱うと失われます。したがって、私たちは関係用語を学び、使用しようとします。あなたがフランスに行って、彼らがアメリカ人を話し、同じ通貨を使うことを期待するとき、それは難しくなります。フランス語の10語を話すことを学び、彼らは両手を広げてあなたを歓迎します、そしてあなたは地元の人々と全く異なる経験をするでしょう。

    とにかく、モデルの実装を進めてください。おそらくいつか変更を加えることになるでしょう。すべてのDDLを保存します。すべてのテストデータを挿入ステートメントとして、またはテーブルのバックアップまたは文字形式のエクスポートとして保存します(MySQLがこの領域で何ができるか/できないかはわかりません)。
    37.1。処理済み、 Officeとのn::n関係 &カテゴリ 。物理モデルに到達したときにのみ、それを「見る」ことができます。

    37.2。完了しました。

    37.3完了。

    38。素晴らしい。同様に短い。 2つのOfficesを持つことは決してできないことに注意してください 同じ郵便番号で。 NUMERIC(5,0)は良いですが、米国は7桁に向かっていると思いました。関係ありません、あなたはそれを理解することができます。 Officeの優れたPKです。 。 Addressの一部であったこの列 、おそらく ZipCode 、重複することなく、より高い目的に昇格されました。これは5つの子テーブルで処理され、PK名を明確にする必要があるため、前述の規則に従って、これを OfficeCodeと呼びます。; OfficeZipCode ばかげているかもしれません。

    Nameに一意のインデックスが必要です 2つのOfficesを追加しないようにするため 同じ名前で。説明のために、これは実際には Officeの論理キーであることに注意してください。 、(StateCode、Town)を置き換えます 、そしてそれはそのままです。

    私はまだあなたがStateCodeを必要とするかもしれないと思います およびTown クイックリファレンスとして( Addressのどこかに座っている場合を除く )

    データモデルが更新され、5番目がレビュー可能になりました。 ... Date について、あなたはあなたの好みを述べませんでした vs ... Dtm 。私は後者を使用します。後者の方がより具体的であり、時間コンポーネントも識別します。簡単に変更できます。

    この回答は最大長に達しました。 「パートII」に続く



    1. CSVをphpmyadminにインポートする

    2. 非表示の機能:ファイル間でアクセスオブジェクトをドラッグアンドドロップします

    3. Perlでのクロール中にMySQLサーバーが消えました

    4. max_allowed_pa​​cketサイズを変更する方法