質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

Q&A

4回答

908閲覧

自己参照テーブルでNOT NULL制約のidをどのように入れたらいいでしょうか

ogeeeeepon

総合スコア0

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

0グッド

1クリップ

投稿2023/05/02 04:43

編集2023/05/02 05:35

実現したいこと

下記サンプル構造で、新規データをエラーなくインサートするにはどのようにしたらいいでしょうか?

前提

編集した履歴用のテーブルを作ると膨大な数になるため一つのテーブルで編集履歴も兼ねたテーブル構成になっていて、特に下記がネックになっています。
copy_idには、
・新規インサートは新規インサート時のPKを入れる ←これがネック
・データ編集時は元のデータのPKを入れる
(データ編集・更新時も新規インサートするが、copy_idは編集元のidを入れる)

削除は物理削除対応です。

サンプルテーブル構造

users テーブル

columnNULL
idPK autoincrement×
copy_idint×
namevarchar×
emailvarchar×
pennamevarchar
created_atdatetime×
updated_atdatetime×

外部キー制約

column対象制約
copy_idusers.idNO ACTION

試したこと

copy_idのNOT NULL制約を外せば簡単に解決するのは分かっているのですが、
外部キー制約もしてかっちり固めたい意図もあるようです。
また、新規インサート時に最新データのPKを取得してそこから次のPKを予想して入れる方法も考えたのですが、危険かな・・と思い止めました。
どのように実現したらいいか、またその他方法などお知恵をお借りいただければと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2023/05/02 05:09

> 一つのテーブルで編集履歴も兼ねたテーブル構成 履歴に関するキーは何ですか? 質問内容では、単に更新しているだけで履歴にはなっていないように見えますが?
ogeeeeepon

2023/05/02 05:31

can110さん id列はオートナンバーで、copy_idはオートナンバーではありません。 ご提示いただいたURLと同じような質問です。 saziさん 履歴に関するキーはcopy_idです。 編集する毎に編集した内容を新たにインサートしますが、編集元がどれか分かるようにcopy_idに編集元のidを入れるというような感じです。
sazi

2023/05/02 07:35 編集

copy_idを更新時に保存してツリー状態にするという事ですね idがオートナンバーなら、新規時にネックになるという意味が分かりません。 オートナンバーは、insert時に指定しなければ新たな番号が振られるわけですから。
guest

回答4

0

たたき台①

🔑idcopy_idnameemailpenname
1 太郎email①子太郎
2 花子email②ハナコ
31太郎email①桃太郎
4 次郎email③小次郎
53太郎email④桃太郎
65タロウemail④桃太郎

たたき台②

🔑idnameemailpenname
1太郎email①子太郎
2花子email②ハナコ
3太郎email①桃太郎
4次郎email③小次郎
5太郎email④桃太郎
6タロウemail④桃太郎
🔑idcopy_id
31
53
65

たたき台③

🔑user_idnewest_namenewest_emailnewest_penname
1タロウemail④桃太郎
2花子email②ハナコ
3次郎email③小次郎
🔑user_id🔑user_row_#nameemailpenname
11太郎email①子太郎
21花子email②ハナコ
12太郎email①桃太郎
31次郎email③小次郎
13太郎email④桃太郎
14タロウemail④桃太郎

投稿2023/05/02 16:30

logres_Fan

総合スコア171

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己結合で自分に外部キー結合するとon updateをno actionにしても参照されているidは変更が効かないのでおそらく運用時にはまると思いますよ。やめたほうが良いと思います。
またどうしてもというならご自身でもご指摘がある通りnullを許容するだけの話です。

上記前提をすっとばして、なんとか運用でカバーしたいなら、id=1をダミーデータとして、初期登録時にはcopy_idに1を入れて投入して、すぐ書き換えるという手はあるでしょう。ただそこまでしてやる必要があるか微妙です。

SQL

1create table users( 2id int primary key auto_increment, 3copy_id int not null default 1, 4val varchar(20), 5foreign key (copy_id) references users(id) on delete no action on update no action); 6 7/* ダミー を投入しておく */ 8insert into users values(1,1,'dummy');

データ投入

SQL

1start transaction; 2insert into users(copy_id,val) values 3(1,'aaa'),(1,'bbb'),(1,'ccc'); 4update users set copy_id=id where copy_id=1; 5commit;

投稿2023/05/02 08:35

yambejp

総合スコア116724

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

構造を変えたくないのであれば、もう一文SQLを記載するのはいかがでしょうか。
具体的にはINSERTの直後にUPDATEをさせる方法です。
直前のINSERTしたidを取ってきてcopy_idに入れるSQLとなります。

投稿2023/05/02 06:23

Mash

総合スコア40

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

また、新規インサート時に最新データのPKを取得してそこから次のPKを予想して入れる方法も考えたのですが、危険かな・・と思い止めました。

PKの自動採番を止めてしまってはどうでしょうか?

投稿2023/05/02 04:58

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問