2

リレーションシップテーブルには4つの列があります。

  1. ID
  2. CID-コースID
  3. LID-関連するレッスンの一意のID
  4. course_based_id-以下の説明

と呼ばれる別のテーブルには、一意のIDを持つレッスンとコースがたくさんありlessonsますcourses。このテーブルは、それらの間の関連付けテーブルです。基本的に、一意のレッスンIDを一意のコースIDに割り当てます。しかし..レッスンのコースベースのIDが必要です。つまり、たとえば、スクリーンショットの1行目と2行目を見てみましょう。

ここに画像の説明を入力してください

ふた1はコース2の最初のレッスン、ふた3はコース2の2番目のレッスンです...など。したがって、cid 2、lid 128を挿入すると、もちろん2番目のレッスンになります。

ここで、問題は、挿入中にこの番号を自動生成したいということです。

$q="INSERT INTO `courses-lessons` (`cid`, `lid`) VALUES (?,?)";

しかし、それを行う方法がわかりません。いくつかのMySQL関数?またはクエリ内の何か?

4

2 に答える 2

4

MyISAMエンジンを使用してこのテーブルを保存している場合、これは比較的簡単に実行できます。フィールドを次のように定義するだけです。

cid INT NOT NULL,
course_based_id INT NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY (cid, course_based_id)

次に、anyはに基づいてINSERT新しい(+1)値を自動的に割り当てます。これがこの概念を説明するフィドルです。course_based_idcid

詳細については、MySQLのドキュメントを参照してください。

残念ながら、InnoDBエンジンにはそのようなメカニズムはありません。したがって、おそらく次のルーチンで逃げることができます(これは擬似コードであり、いくつかのニュアンスがあります)。

1) lock table for writing; 
2) @x = SELECT MAX(course_based_id) WHERE cid = %cid_to_be_inserted%;
3) INSERT (..., course_based_id) VALUES (..., @x + 1);
4) unlock table;

この答えを確認することをお勧めします; これはMySQLではなくPostgreSQL用ですが、1つの可能な実装について詳細に説明しています。

更新:その動作を実装する実際のクエリセットの例を次に示します。

CREATE TABLE tx
  (id INT NOT NULL, cid INT NOT NULL, lid INT NOT NULL,
   course_based_id INT NOT NULL,
   PRIMARY KEY (id),
   UNIQUE KEY (cid, course_based_id)
);

LOCK TABLE tx WRITE, tx AS t READ;

INSERT INTO tx (id, cid, lid, course_based_id)
  SELECT 2, 2, 1, 
         1 + COALESCE(
               (SELECT MAX(course_based_id) 
                  FROM tx AS t 
                 WHERE cid = 2), 
             0);

 INSERT INTO tx (id, cid, lid, course_based_id)
   SELECT 3, 2, 3, 
          1 + COALESCE(
                (SELECT MAX(course_based_id) 
                  FROM tx AS t WHERE cid = 2),
              0);

 UNLOCK TABLES;

ご覧のとおり、次のcourse_based_id値を直接計算することはできませんが、ここでシーケンスを取得しました。

于 2012-09-05T22:10:30.490 に答える
2

参照整合性(外部キー)が必要な場合は、InnoDBを使用しているため、(優れた)MyISAMトリックは機能しません。

あなたができることはcourse_based_id、テーブルへの挿入中にそれらを生成することです。

挿入を実行し、他のコードがこのテーブルに挿入されないようにする-それほど複雑ではない-プロシージャを記述します-このプロシージャを実行します。また、更新の手順(​​および、このcourse_based_idにギャップがある場合は削除の手順)も必要です。

したがって、代わりに:

INSERT INTO courses_lessons 
  (cid, lid) 
VALUES 
  ( ?cid, ?lid ) ;

エラー(重複など)をキャッチするために、ストアドプロシージャに囲まれています。

INSERT INTO courses_lessons 
  (cid, lid, course_based_id) 
SELECT 
  ?cid, ?lid, 
  1 + COALESCE( ( SELECT MAX(course_based_id) 
                  FROM courses_lessons 
                  WHERE cid = ?cid
                ), 0)
FROM
  dual ;

idこのテーブルでは、実際には列は必要ありません。(cid, lid) 行を識別するには、主キーをオンにするだけで十分です。また、次の場所に一意のキーを追加する必要があります(cid, course_based_id)

ALTER TABLE courses_lessons 
  ADD CONSTRAINT UQ_cid_course_based_id
    UNIQUE cid_course_based_id_UQ
      (cid, course_based_id) ;
于 2012-09-05T22:36:41.570 に答える