Mysql 4日目データベース設計

6574 ワード

プライマリ・スペア、クラスタなどのシナリオを考慮せず、ビジネス上の設計に基づいて主にテーブル構造とテーブル間関係の設計を行う.
テーブル内のフィールドについては、主にビジネスに基づいて定義されています.
  • ストレージエンジンは一般的にInnoDBを使用し、特殊需要は
  • を特殊に選択する.
  • 文字セットとチェックルール特にチェックルールとは、A=aでは大文字と小文字を区別せずorder byなどに影響する2文字間の比較ルールのこと.binは一般的に大文字と小文字を区別し、一般的にgeneral
  • を用いる.
  • フィールド定義フィールド選択タイプ
  • インデックスの後に
  • と言います.
  • 特殊用途表例えばキャッシュ、要約等
  • フィールドのデータ型選択
    3つの原則:
  • より小さいデータ型、例えばtiny intでint
  • を使わないことができる.
  • より簡単なデータ型、intはvarcharより簡単で、より少ないディスクと操作に必要なCPUが使用されます.例えばintでip
  • を格納する.
  • nullはできるだけ避ける.できるだけnot null文を使用すると、nullは追加のストレージスペースをもたらし、インデックスを追加した後も特別な処理が必要になります.

  • 整数
  • [UNSIGNED] TINYINT, SMALLINT, INT,BIGINT. 範囲が広がる.明らかに小さいほど省スペース
  • は、幅INT(11)を指定することができる.これはインタラクティブツールの表示幅だけで、実際の範囲とは関係なく、定義時に指定しなくてもよいし、効率も向上する
  • .
  • 構築テーブルはzerofillを選択できる
  • です.
    実数
  • floatとdoubleは不正確なタイプ
  • です.
  • は精度double(12,4)が全桁と小数桁であることを指定できますが、挿入時に超過部分を四捨五入するので指定しないことをお勧めします.
  • また、浮動小数点数を用いる2進数表現に変換して記憶または計算を行うため、
  • のような精度の問題が生じる可能性がある.
    update biz_pay_task set order_price = 131.07232;
    //         131.07233
  • decimalは正確な小数点を記憶するために使用され、同様に浮動小数点型よりも複数の記憶範囲を占有し、計算時にdoubleに変換されるため、
  • を必要としない.
  • の再設計上、decimalの代わりにbigintを用いることも考えられる.

  • 文字列タイプ
  • CHARは一定長であるため、頻繁に更新する際に破片
  • が発生しにくい.
  • CHARはMD 5を記憶するのに適しているこの結果は、一定長のデータ
  • である.
  • CHARは、フラグビットなどの小さなバイトを記憶するのに適しており、VARCHARよりも空間
  • を節約することができる.
  • VCHARは長くなり、頻繁に更新すると破片
  • があります.
  • BINARYはバイナリ文字列であり、バイナリの字面表現であり、ソートなどはバイナリ数に変換する
  • を行う.
  • IPアドレス、これは特別に扱うことができて、INET_を使いますATON()とINET_NTOA()は、ipアドレスを符号なし数
  • として保存する.
    時間タイプ
  • DATETIME 19ビット標準表示、date_を使用可能formatによる構造化クエリ
  • TIMESTAMP 19ビット表示で、範囲はDATETIMEより小さいが、省スペースでNULLにはならない.
  • TIMESTAMPは自動更新を設定することができ、updatetimeのようなフィールド
  • に適している.
    プライマリ外部キー
    プライマリキー
  • は、プライマリ・キーがインデックスとして返されるため、コンパクトであればあるほど小さくなるが、実際にはソートが良い.
  • uuidを使いたい人もいるかもしれませんが、長いのでUNHEX()関数を使って数字に変更してBINARYに保存し、検索するときはHEX()メソッドを使ってさらに16進数フォーマット
  • に変更したほうがいいです.
    外部キー
  • では、外部キーを削除するコンストレイント動作のデフォルトエラーを設定できます.cascadeも削除され、no actionは何もしませんが、一貫性が破壊されます.
  • set foreign_を使用することもできます.key_checks=0はチェックを一時的にオフにすることで、バックアップなどの特殊な操作でパフォーマンスを向上させることができます.

  • 表フィールドの外で、どのように表を切断して区分するかは、モデルの主な議論の問題です.
    3つのパターン
    5パターンの実用性が低いので、3つのパターンだけを考慮して学生選択の授業表Student_Course(studentId, studentName, collegeId, collegeName, courseId, courseName, credit)
    第1のパターン列の値は切断できません
    上の学生が複数の授業を選んだら、courseNameで使用し、番号を分割する方法があります.これは明らかに第1のパターンを満たすことができない.この統合プライマリ・キーとして(studentId,courseId)を使用する方法もあります.これにより、多くの重複行が発生します.これも古典的な多対多関係が引き起こした問題である.
    第2のパターンは部分依存性を除去する
    1対複数を2対複数に分割する1対複数のデータstudentNameの部分依存性(studentId,courseId)は、次のような問題を導入すると考えられます.
  • データ冗長性:1人でNゲートを選択するとstudentName,collegueId,collegueName,courseName,creditがn回繰り返されます.
  • エラーの更新が容易です.例えばcreditを変更した場合、多くの行
  • を変更する必要があります.
  • 新しいコースを開設した場合、誰も選択していなければ
  • を挿入できません.
  • コースを選択していないと、コースも削除されます.修正後の設計:Student(studentId,studentName,collegeId,collegeName)Course(courseId,courseName,credit 1)Student_Course(studentId, courseId)

  • 第3のパターンは伝達依存性を解消する
    伝達依存と部分依存は混同されやすい.この表が何に適用されるかに大きな関係があるこの部分の主な目的は、重複データをさらに除去することであり、上記のような1対以上の学生カリキュラム表を提案し、その主コードは明らかにstudentIdとcourseIdである.これにより、第2のパターン分解後のstudentテーブルに部分的に依存していると判断しやすく、学生情報のプライマリ・キーはstudentIdであるべきであり、また、彼以外にプライマリ・キーとして機能しないが、別のフィールドである可能性があるため、コードのフィールド:collegeIdである.こうしてStudentId->collegeId->collegeNameとなります.これが伝達依存です.さらに切断後:Student(studentId,studentName,collegeId)Collegue(collegeId,collegeName)
    パターンと逆パターン
    パターンの長所と短所:-重複を減らす-更新を高速にする-groupbyなどの文を必要としない-短所:クエリー時に関連がより多くなる
    逆パターンのメリットとデメリット:-デメリット:冗長行および更新エラーの可能性-関連付ける必要はありません
    いくつかの取捨選択は、パターンと逆パターンを混用する必要がある場合があります.特に、インデックス、統計、並べ替えに追加のフィールドが必要な場合があります.これは更新上のトラブルをもたらす可能性があり、実際の状況に応じて具体的に考慮する必要があります.
    その他のアプリケーション
  • 要約表は通常、タイミングの計算のいくつかの要約情報であり、レポートシステムは比較的多くの
  • を使用する.
  • キャッシュ・テーブルは、例えばMyISAMエンジンを使用してテーブルを構築し、インデックスの作成として残す.これにより、インデックスとして使用可能なすべてのフィールドを1つのテーブルに個別に提出し、インデックスを高速化できます.この場合、テーブル分割技術では
  • が用いられる場合もある.
  • カウンタテーブル
  • CREATE TABLE counter( cnt int unsigned not null DEFAULT 0 ) ENGINE = InnoDB;

    挿入するたびに1を増やし、そのたびにこの行を排他的にロックします.より良い解決方法:
    CREATE TABLE counter( slot tinyint unsigned not null primary key, cnt int unsigned not null DEFAULT 0 ) ENGINE = InnoDB;
    UPDATE hit_counter SET cnt = cnt + 1 where slot = FLOOR(RAND() * 100);

    そして、100行のデフォルトデータを挿入して更新すると、同時ロックを最小限に抑えることができ、SUMフィールドを使って総クリック数を算出することができます.
    毎日計算する必要がある場合、可能なテーブル構造は次のとおりです.
    CREATE TABLE counter( day date not null;
        slot tinyint unsigned not null,
        cnt int unsigned not null DEFAULT 0,
        primary key(day, slot)
    ) ENGINE = InnoDB;
    
    INSERT INTO counter VALUES(CURRENT_DATE, FLOAT(RAND() * 100), 1) ON DUPLICATE KEY UPDATE cnt = cnt + 1;

    ON DUPLICATE KEY、重複キーが発生した場合更新は新規ではありません.
    ##DDL DDLを高速化すると、サービスがブロックされるので、早ければ早いほど良いはずです.一般的な方法では、このリポジトリがあります.オブジェクト化ビューフェイスブックのツールで動的に変更できるテーブルを再作成します.