MySQL では、自動インクリメントする 2 つの異なるテーブルに列を持つことは可能ですか? 例: table1 には「secondaryid」の列があり、table2 にも「secondaryid」の列があります。table1.secondaryid と table2.secondaryid に同じ情報を保持させることは可能ですか? table1.secondaryid は値 1、2、4、6、7、8 などを保持でき、table2.secondaryid は値 3、5、9、10 を保持できますか? これには 2 つの理由があります。1) 2 つのテーブルは「いいね」の別のテーブルで参照されます (ユーザーが Facebook のページを気に入ったのと同様)、2) table2 のデータは主キーを使用する table1 のサブセットです。したがって、table2 に格納されている情報は、異なるカテゴリのトピックであるため、table1 に依存しています。(カテゴリは table1、トピックは table2)。
7 に答える
カテゴリとトピックを 2 つの別々のテーブルで区別したいようですが、両方の ID を別のテーブルで参照して、likes
ユーザーがカテゴリまたはトピックを好むようにします。
できることは、サブタイプcategories
とを持つスーパー エンティティ テーブルを作成することですtopics
。自動インクリメントされたキーは、スーパー エンティティ テーブルで生成され、2 つのサブタイプ テーブルのうちの 1 つだけに挿入されます (それがカテゴリかトピックかに基づいて)。
サブタイプ テーブルは、自動インクリメント フィールドを介して 1:1 の関係でこのスーパー エンティティを参照します。
likes
このように、 1 つの列 (カテゴリまたはトピックのいずれかを表すことができます) に基づいてスーパーエンティティ テーブルをテーブルにリンクするだけid
で、両方のサブタイプ テーブルに no が存在します。
これをモデル化する方法の簡単な例を次に示します。
このモデルでは、カテゴリとトピック間の関係を維持できますが、両方のエンティティをsuperentity
テーブルで一般化できます。
このモデルのもう 1 つの利点は、サブタイプ テーブルの共通フィールドをスーパーエンティティ テーブルに抽象化できることです。たとえば、categories
とtopics
の両方にフィールド と が含まれていたtitle
とurl
します。これらのフィールドは、superentity
そのサブタイプの共通の属性であるため、テーブルに配置できます。サブタイプ テーブルに固有のフィールドのみをサブタイプ テーブルに入れます。
テーブル間で auto_increment 値を共有することはできませんが、次のように見せることはできます。
set @@auto_increment_increment=2; // change autoinrement to increase by 2
create table evens (
id int auto_increment primary key
);
alter table evens auto_increment = 0;
create table odds (
id int auto_increment primary key
);
alter table odds auto_increment = 1;
これの欠点は、グローバル設定を変更しているため、すべての auto_inc フィールドが 1 ではなく 2 ずつ増加することです。
2 つのテーブルの ID を異なるものにしたい場合は、最初に table2 の AUTO_INCREMENT を大きな数値に設定できます。
ALTER TABLE `table2` AUTO_INCREMENT=1000000000;
PosgreSQL などの DBMS にある、シーケンスに相当する MySQL が必要なようです。これにはいくつかの既知のレシピがあり、そのほとんどは、シーケンスの名前を追跡するテーブルと、現在の値を保持する整数フィールドを作成することを伴います。このアプローチにより、シーケンスを含むテーブルをクエリし、必要に応じて 1 つ以上のテーブルでそれを使用できます。
この問題について興味深いアプローチをしている記事がここにあります。また、現在は廃止されたDB PEAR モジュールでこのアプローチが使用されていることも確認しました。
他のテーブルのインクリメント値は、クライアントまたは mysql 内で sql 関数を介して手動で設定する必要があります。
ALTER TABLE users AUTO_INCREMENT = 3
したがって、table1 に挿入した後、最後の自動インクリメントを取得し、それによって他のテーブルの自動インクリメント フィールドを変更します。
トリガーでそれを行うことができます:
-- see http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id
CREATE TABLE sequence (id INT NOT NULL);
INSERT INTO sequence VALUES (0);
CREATE TABLE table1 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
secondardid INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
CREATE TABLE table2 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
secondardid INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (id)
);
DROP TRIGGER IF EXISTS table1_before_insert;
DROP TRIGGER IF EXISTS table2_before_insert;
DELIMITER //
CREATE
TRIGGER table1_before_insert
BEFORE INSERT ON
table1
FOR EACH ROW
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
NEW.secondardid = LAST_INSERT_ID();
END;
//
CREATE
TRIGGER table2_before_insert
BEFORE INSERT ON
table2
FOR EACH ROW
BEGIN
UPDATE sequence SET id=LAST_INSERT_ID(id+1);
NEW.secondardid = LAST_INSERT_ID();
END;
//
私はあなたの質問に混乱しています。テーブル 2 がテーブル 3 のサブセットである場合、主キーの値を共有する必要があるのはなぜですか。カテゴリが表 2 と表 3 に分かれているということですか。
もしそうなら、それらを別々のテーブルに入れるという設計上の選択に疑問を呈します。2 つの異なる状況のいずれかを抱えているようです。1 つ目は、2 つのフレーバーがある "カテゴリ" エンティティがあることです。この場合、おそらくカテゴリのタイプを指定するタイプ列を持つ単一のカテゴリ テーブルが必要です。
2 つ目は、ユーザーが異なるものを「気に入る」ことができるということです。この場合、「user likes」テーブルには、オブジェクトごとに個別の外部キーが必要です。複合外部キーを使用してトリックを実行できます。その後、オブジェクトのタイプと通常の数値 ID が得られます。したがって、like テーブルには「type」と「id」があります。person テーブルには、"PERSON" で満たされた列と、数値 ID で満たされた別の列があります。そして、結合は「a.type = b.typeおよびa.id = b.idで」と言うでしょう。(または、「タイプ」の部分は、テーブルの選択において暗黙的である可能性があります)。