1

MySQL をバックエンドとして使用して、データ ウェアハウスを作成しています。2 つの整数 ID と名前文字列に基づいてテーブルを分割する必要があります。パーティショニングに関する mySQL ドキュメント (の一部) を読みましたが、このシナリオで最も適切なパーティショニング スキームは、HASH または KEY パーティショニングのいずれかです。

私は、自分のフィールドに「衝突のない」ハッシュ アルゴリズムを提供する責任を負いたくないので、KEY パーティショニングを選択しました。代わりに、ハッシュに必要なキーを生成するために MySQL ハッシュに依存しています。

以下に、次のフィールドの COMPOSITE に基づいて分割したいテーブルのスキーマのスニペットを含めました。

学校 id、course_id、ssname (学生の姓)。

ところで、これが学校関連の情報を保存する最良の方法ではないことを誰かが指摘する前に、私がモデル化しようとしているもののアナロジーとして以下のケースを使用しているだけであることを指摘しておく必要があります。

現在の CREATE TABLE ステートメントは次のようになります。

CREATE TABLE foobar (
    id         int UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    school_id  int UNSIGNED NOT NULL,
    course_id  int UNSIGNED NOT NULL,
    ssname     varchar(64) NOT NULL,

    /* some other fields */

    FOREIGN KEY (school_id) REFERENCES school(id) ON DELETE RESTRICT ON UPDATE CASCADE,

    FOREIGN KEY (course_id) REFERENCES course(id) ON DELETE RESTRICT ON UPDATE CASCADE,

    INDEX idx_fb_si (school_id),
    INDEX idx_fb_ci (course_id),
    CONSTRAINT UNIQUE INDEX idx_fb_scs (school_id,course_id,ssname(16))
) ENGINE=innodb;

この質問の冒頭で述べた 3 つのフィールド (つまり、school_id、course_id、および生徒の姓の最初の文字) を使用してテーブルが分割されるように、上記のステートメントを変更する方法を知りたいと思います。

私が尋ねたいもう一つの質問はこれです:

たとえば、有効な* school_id、course_id、または姓を含むレコードを挿入しようとすると、基になるパーティション テーブル ファイルが存在しない場合、mySQL によって基になるファイルが自動的に作成されます。

適例。私は次の学校を持っています: New York Kindergaten、Belfast Elementary、および次のコース: Infitesmal 次元の嘘代数、もつれた実体

また、次の学生 (姓) がいると仮定します: ブッシュ、ブレア、フセイン

新しい学校 (またはコース、または学生) を追加するとき、それらを foobar テーブルに挿入できますか (実際、そうしない理由はわかりません)。私が尋ねる理由は、学校やコースなどを追加することを予見しているためです。つまり、mySQL は舞台裏で追加のテーブルを作成する必要があります (ハッシュが新しいキーを生成するため)。

この分野の経験を持つ誰かが (できれば彼らの主張を裏付けるリンクで) 確認できれば、私の理解 (つまり、新しい学校、コース、または学生をデータベースに追加する場合、手動による管理は必要ありません) が正しいことを確認できれば幸いです。

私の2番目の質問が適切に形成された(明確な)かどうかはわかりません。そうでない場合は、さらに明確にさせていただきます。

*VALID - 有効とは、参照整合性を壊さないという点で有効であることを意味します。

4

1 に答える 1

2

パーティショニングがあなたが思っているほど役に立つとは思えません。そうは言っても、あなたが求めているものには他にもいくつかの問題があります(注:この回答全体がMySQL 5に適用されます。バージョン6は異なる場合があります):

  • KEY パーティショニングで使用される列は、主キーの一部である必要があります。school_idcourse_idおよびssname主キーの一部ではありません。
  • より一般的には、すべての UNIQUE キー (主キーを含む) には、パーティション内のすべての列が含まれている必要があります1。これは、UNIQUE キーの列の交差部分でのみ分割できることを意味します。あなたの例では、交差点は空です。
  • ほとんどのパーティショニング スキーム (KEY 以外) では、整数値または null 値が必要です。NULL でssnameない場合、整数値にはなりません。
  • 外部キーとパーティショニングは同時にサポートされていません2。これは、パーティショニングを使用しないという強い主張です。

幸いなことに、衝突のないハッシュは心配する必要のないものの 1 つです。なぜなら、パーティショニングによって衝突が発生するからです (そうしないと、各パーティションに 1 つの行しかありません)。上記の問題とパーティショニング式で使用される関数の制限を無視できる場合は、次のように HASH パーティションを作成できます。

CREATE TABLE foobar (
    ...
) ENGINE=innodb
  PARTITION BY HASH (school_id + course_id + ORD(ssname))
  PARTITIONS 2
;

動作するのは次のとおりです。

CREATE TABLE foobar (
    id         int UNSIGNED NOT NULL AUTO_INCREMENT,
    school_id  int UNSIGNED NOT NULL,
    course_id  int UNSIGNED NOT NULL,
    ssname     varchar(64) NOT NULL,

    /* some other fields */

    PRIMARY KEY (id, school_id, course_id),
    INDEX idx_fb_si (school_id),
    INDEX idx_fb_ci (course_id),
    CONSTRAINT UNIQUE INDEX idx_fb_scs (school_id,course_id,ssname)
) ENGINE=innodb
      PARTITION BY HASH (school_id + course_id)
      PARTITIONS 2
;

また:

CREATE TABLE foobar (
    id         int UNSIGNED NOT NULL AUTO_INCREMENT,
    school_id  int UNSIGNED NOT NULL,
    course_id  int UNSIGNED NOT NULL,
    ssname     varchar(64) NOT NULL,

    /* some other fields */

    PRIMARY KEY (id, school_id, course_id, ssname),
    INDEX idx_fb_si (school_id),
    INDEX idx_fb_ci (course_id),
    CONSTRAINT UNIQUE INDEX idx_fb_scs (school_id,course_id,ssname)
) ENGINE=innodb
      PARTITION BY KEY (school_id, course_id, ssname)
      PARTITIONS 2
;

テーブルを格納するファイルに関しては、MySOL はそれらを作成しますが、行がテーブルに挿入されるときではなく、テーブルを定義するときに作成される場合があります。MySQL がファイルを管理する方法について心配する必要はありません。PARTITIONS *n*句によってテーブルを作成するときに定義されるパーティションの数には制限があることに注意してください。

于 2009-12-21T13:21:14.063 に答える