現状・知りたいこと
WEBサイトに以下の機能を実装中です。
➀ ユーザがアイテムを「フォルダへ保存」できる
➁「フォルダへ保存」するとデフォルトフォルダに入り、フォルダ間でアイテムを移動できる
➂ フォルダはユーザが任意に作成でき、デフォルトフォルダは任意に変更できる
そして「1ユーザごとに、1つのデフォルトフォルダ」と制約したいのですが、そのための適切な方法を知りたいです。
発生している問題
以下のようにCREATE TABLE
しましたが、「1ユーザごとに、1つのデフォルトフォルダ」が制約できません。
つまり以下ではis_default=true
のレコードを、1ユーザが複数持ててしまいました。
SQL
1CREATE TABLE users ( 2 id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 name VARCHAR(100) NOT NULL 4); 5 6CREATE TABLE folders ( 7 id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 8 user_id INT UNSIGNED NOT NULL, 9 name VARCHAR(100) NOT NULL, 10 is_default BOOLEAN DEFAULT false, 11 CONSTRAINT `folders__foreign__user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) 12);
自分なりの案
いくつか案を考えてみましたが、このどれが適切なのか?それとも他に適切な方法があるのか?がわかりません。
案1
folders.is_default
というカラムは削除し、default_folders
というリレーションテーブルを作り、以下のようにする案です。
SQL
1CREATE TABLE default_folders ( 2 id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 user_id INT UNSIGNED NOT NULL, 4 folder_id INT UNSIGNED NOT NULL, 5 UNIQUE `default_folders__unique__user_id` (`user_id`), 6 CONSTRAINT `default_folders__foreign__user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`), 7 CONSTRAINT `default_folders__foreign__folder_id` FOREIGN KEY (`folder_id`) REFERENCES `folders`(`id`) 8);
しかしわざわざ別テーブルを作ることが適切なのか?判断できません。
「なんかテーブルって少ない方が良さそうだよなぁ」という印象があります。
案2
folders.is_default
というカラムは削除し、users
テーブルにdefault_folder_id
カラムを設け、以下のようにする案です。
SQL
1CREATE TABLE users ( 2 id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, 3 name VARCHAR(100) NOT NULL, 4 default_folder_id INT UNSIGNED NOT NULL, 5 -- しかし以下の外部キー制約を課すとジレンマが生じる 6 CONSTRAINT `users__foreign__default_folder_id` FOREIGN KEY (`default_folder_id`) REFERENCES `folders`(`id`) 7);
しかし上のコメントにあるように、users__foreign__default_folder_id
という外部キー制約を課すと、以下ABというジレンマが生じてしまいます。
A: users
へのINSERT
の前に、folders
へのINSERT
が必要 (users__foreign__default_folder_id
のため)
B: folders
へのINSERT
の前に、users
へのINSERT
が必要 (folders__foreign__user_id
のため)
このジレンマの解消は、INSERT
のときはデータベースになんからのロックをかけて、次のPKを取得するという方法で回避できますが、そういう方法が適切なのか?判断できません。
「なんかロックって遅そうだよなぁ」という印象があります。
まとめ
以上の2案についてどちらが適切か、または他にオススメの案がございましたら教えて頂けませんでしょうか?
適切さは全体の仕様次第でしょうけれど、WEBサイト制作経験がなくまるで判断できない状況です。
「まぁ私ならこうするな」「普通だったらこうだよ」「こうするとこういうとき便利だよ」など、経験豊富な皆様からのご意見を頂戴し、判断の指針にさせて頂ければと思っています。
バージョン
php 👉 8.2
MySQL 👉 5.7
よろしくお願い致します。
回答3件
あなたの回答
tips
プレビュー