こんにちは
my_add_fk
関数の呼び出しが何かの関数の中などではなく PHP ファイルのトップレベルに記述されているので、このプログラムが記述されているファイルが読み込まれるたびに実行されます。
両方のテーブルが2つとも作られた時点で1度だけ ADD FOREIGN KEY
すればいいんじゃないでしょうか。
こんにちは
いつもお世話になっております
>両方のテーブルが2つとも作られた時点で1度だけ ADD FOREIGN KEY すればいいんじゃないでしょうか。
とのことですが、どのようにすればできますか?次の【A1】と【A2】の二回を、【B1】の一回に変更する、という意味ではないですよね?
—
質問では下記【A1】と【A2】という二回のステップに分けてやっていまして、
【A1】 my_add_fk()をコメントアウトし、my_create_table()を書いた状態でサイトを読み込みテーブル作成を実行
【A2】my_create_table()をコメントアウトし、my_add_fk()を書いた状態でサイトを読み込みFK設定を実行
アドバイスを受けて下記【B1】の一回だけにしてみたのですが、やはりFKは複数入ってしまいました。
【B1】 my_add_fk()とmy_create_table()を書いた状態でサイトを読み込みテーブル作成とFK設定を実行
また複数がいくつになるかの法則を見つけまして、my_create_table()で設定したカラムの数だけFKが追加される、といった法則でした。
つまり以下のようにカラムが3つあればFKは3ついった流れです。
まずは【A1】を実行し、SHOW CREATE TABLE wp_yasai;
を実行
↓ 結果
'CREATE TABLE'wp_yasai' (
'post_id' bigint(20) unsigned NOT NULL AUTO_INCREMENT,
'kind_id' int(2) unsigned NOT NULL,
'content' varchar(10) DEFAULT NULL,
PRIMARY KEY ('post_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8'
そして【A2】を実行し 、SHOW CREATE TABLE wp_yasai;
を実行
↓ 結果
'CREATE TABLE'wp_yasai' (
'post_id' bigint(20) unsigned NOT NULL AUTO_INCREMENT,
'kind_id' int(2) unsigned NOT NULL,
'content' varchar(10) DEFAULT NULL,
PRIMARY KEY ('post_id'),
KEY 'kind_id' ('kind_id'),
CONSTRAINT 'wp_yasai_ibfk_1' FOREIGN KEY ('kind_id') REFERENCES 'wp_kinds' ('kind_id'),
CONSTRAINT 'wp_yasai_ibfk_2' FOREIGN KEY ('kind_id') REFERENCES 'wp_kinds' ('kind_id'),
CONSTRAINT 'wp_yasai_ibfk_3' FOREIGN KEY ('kind_id') REFERENCES 'wp_kinds' ('kind_id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8'
ご覧のようにwp_yasai_ibfk_1
とwp_yasai_ibfk_2
とwp_yasai_ibfk_3
という3つのFKになってしまうのです
(尚こちらの入力フォームの事情により、上記の結果はバッククオートをアポストロフィーに変換しています。)
以下のように「FKが設定されていなければ」という条件でもあればと思っているのですが、なかなか検索しても見つけられません…
function my_add_fk($child_table, $child_col, $parent_table, $parent_col){
global $wpdb;
if( 「FKが設定されていなければ」 ){
$wpdb->query("ALTER TABLE $child_table ADD FOREIGN KEY($child_col) REFERENCES $parent_table($parent_col)");
}
}
私の書いた意図は、繰り返しになりますがADD FOREIGN KEY
に必要なテーブルが両方CREATE
された時点でADD FOREIGN KEY
を実行すれば良いということです。
(この言い方が正確か分かりませんが、2つめのテーブルをCREATE
したときにです)
CREATE TABLE
がいつ実行されるのか、FOREIGN KEY に必要なカラム名はどのように生成されているのかなどのロジックが分からないので、具体的にこういうロジックでやればできるとは言いにくいですが。
参照する側であれ参照される側であれ、どちらのデータベースをCREATE
するときも、それぞれのテーブル名と外部キーに関連したカラム名が決定しているのであれば、CREATE
時に他方のデータベースが存在する場合にのみADD FOREIGN KEY
すれば良いのではないでしょうか。
まさか同じテーブルのCREATE
を複数回実行はしないと思いますので、ロジック上は1回しかADD FOREIGN KEY
されません。
ロジックがややこしければ、DROP FOREIGN KEY
してからADD FOREIGN KEY
すれば1つしか生成されません。
ただ、追加する度にインデックスを追加するコストがかかりまが、データベースにデータがほとんどなければそのようなコストは無視できると思います。
ちょっと説明が冗長になってしまいましたが、wp_kinds
テーブルが作成されたときにADD FOREIGN KEY
すれば良いのではないでしょうか。
>wp_kindsテーブルが作成されたときにADD FOREIGN KEYすれば良い
なるほど!わかったかもしれません。
つまり下記34行目(#ここでwp_yasaiテーブルにFKを追加(※1)
のコメントの次の行)でFKをセットするという感じであっていますか?
// wp_yasaiテーブル作成
my_create_table('yasai');
function my_create_table( $table_name ) {
global $wpdb;
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
$sql = "CREATE TABLE " . $wpdb->prefix . $table_name . "(
post_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT
,kind_id INT(2) UNSIGNED NOT NULL
,content VARCHAR(10)
,PRIMARY KEY (post_id)
#kindsテーブルのCREATEが終わってから下記を実行するのでここではコメントアウト(※1)
#,FOREIGN KEY (kind_id) REFERENCES wp_kinds(kind_id)
);";
add_option($table_name."_version", '1.0');
dbDelta($sql);
}
// wp_kindsテーブル作成
my_create_table('kinds');
fnction my_create_table( $table_name ) {
global $wpdb;
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
$sql = "CREATE TABLE " . $wpdb->prefix . $table_name . "(
kind_id INT(2) UNSIGNED NOT NULL AUTO_INCREMENT
,kind VARCHAR(10)
,PRIMARY KEY (kind_id)
);";
add_option($table_name."_version", '1.0');
dbDelta($sql);
#ここでwp_yasaiテーブルにFKを追加(※1)
my_add_fk( 'wp_yasai', 'kind_id', 'wp_kinds', 'kind_id' );
}
// 外部キー追加
function my_add_fk($child_table, $child_col, $parent_table, $parent_col){
global $wpdb;
$wpdb->query("ALTER TABLE $child_table ADD FOREIGN KEY($child_col) REFERENCES $parent_table($parent_col)");
}
できれば教えて頂きたいのですが、@munyagu 様もこのようにしますか?
自分なりに12行目のコメントアウトで「FKを別のタイミングで設定します」ということを伝えているつもりですが、やはりタイミングが別だとわかりにくいというか…、でも仕方ないですもんね。何かわかりやすい方法があればいいのですが。
書かれている処理が書かれている通りのものなのであれば、
my_create_table('yasai');
と
my_create_table('kinds');
の順番を逆にすれば yasai のCREATE TABLE
の SQL 中で外部キーを追加できます。
しかし、書かれているプログラムが書かれた PHP ファイルがいつ読み込まれるものなのか、何のためにいつ実行されるべきものか分からないので、私ならどう書くかは分かりません。
たしかにそうですね。
手掛かりの少ない中でご回答ありがとうございました。
大変勉強になりました。