Bagaimana menemukan semua tabel yang memiliki kunci asing yang mereferensikan table.column tertentu dan memiliki nilai untuk kunci asing itu?

272

Saya punya tabel yang kunci utamanya direferensikan di beberapa tabel lain sebagai kunci asing. Sebagai contoh:

  CREATE TABLE `X` (
    `X_id` int NOT NULL auto_increment,
    `name` varchar(255) NOT NULL,
    PRIMARY KEY  (`X_id`)
  )
  CREATE TABLE `Y` (
    `Y_id` int(11) NOT NULL auto_increment,
    `name` varchar(255) NOT NULL,
    `X_id` int DEFAULT NULL,
    PRIMARY KEY  (`Y_id`),
    CONSTRAINT `Y_X` FOREIGN KEY (`X_id`) REFERENCES `X` (`X_id`)
  )
  CREATE TABLE `Z` (
    `Z_id` int(11) NOT NULL auto_increment,
    `name` varchar(255) NOT NULL,
    `X_id` int DEFAULT NULL,
    PRIMARY KEY  (`Z_id`),
    CONSTRAINT `Z_X` FOREIGN KEY (`X_id`) REFERENCES `X` (`X_id`)
  )

Sekarang, saya tidak tahu berapa banyak tabel yang ada di database yang berisi kunci asing ke dalam X seperti tabel Y dan Z. Apakah ada query SQL yang bisa saya gunakan untuk kembali:

  1. Daftar tabel yang memiliki kunci asing ke X
  2. DAN tabel mana yang benar-benar memiliki nilai dalam kunci asing
Mel
sumber

Jawaban:

384

Ini dia:

USE information_schema;
SELECT *
FROM
  KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_NAME = 'X'
  AND REFERENCED_COLUMN_NAME = 'X_id';

Jika Anda memiliki banyak basis data dengan nama tabel / kolom yang serupa, Anda mungkin juga ingin membatasi kueri Anda ke basis data tertentu:

SELECT *
FROM
  KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_NAME = 'X'
  AND REFERENCED_COLUMN_NAME = 'X_id'
  AND TABLE_SCHEMA = 'your_database_name';
Alex N.
sumber
7
SELECT TABLE_NAME lebih baik daripada SELECT *
zloctb
Untuk jenis DB apa ini berguna? MySql?
Cirelli94
2
@ Cirelli94 Pertanyaan ini ditandai sebagai pertanyaan MySQL.
mikeschuld
61

Manual Referensi MySQL 5.5: "InnoDB dan FOREIGN KEY Kendala"

SELECT
  ke.REFERENCED_TABLE_SCHEMA parentSchema,
  ke.referenced_table_name parentTable,
  ke.REFERENCED_COLUMN_NAME parentColumnName,
  ke.TABLE_SCHEMA ChildSchema,
  ke.table_name childTable,
  ke.COLUMN_NAME ChildColumnName
FROM
  information_schema.KEY_COLUMN_USAGE ke
WHERE
  ke.referenced_table_name IS NOT NULL
  AND ke.REFERENCED_COLUMN_NAME = 'ci_id' ## Find Foreign Keys linked to this Primary Key
ORDER BY
  ke.referenced_table_name;
Ovidiu
sumber
21

Solusi ini tidak hanya akan menampilkan semua relasi tetapi juga nama kendala, yang diperlukan dalam beberapa kasus (mis. Drop constraint):

SELECT
    CONCAT(table_name, '.', column_name) AS 'foreign key',
    CONCAT(referenced_table_name, '.', referenced_column_name) AS 'references',
    constraint_name AS 'constraint name'
FROM
    information_schema.key_column_usage
WHERE
    referenced_table_name IS NOT NULL;

Jika Anda ingin memeriksa tabel dalam database tertentu, tambahkan berikut ini:

AND table_schema = 'database_name';
Panayotis
sumber
15

Anda dapat menemukan semua informasi terkait skema di information_schematabel yang diberi nama dengan bijak .

Anda mungkin ingin memeriksa tabel REFERENTIAL_CONSTRAINTSdan KEY_COLUMN_USAGE. Yang pertama memberi tahu Anda tabel mana yang dirujuk oleh orang lain; yang terakhir akan memberi tahu Anda bagaimana bidang mereka terkait.

Seb
sumber
5

Daftar semua kunci asing di db termasuk deskripsi

    SELECT  
    i1.CONSTRAINT_NAME, i1.TABLE_NAME,i1.COLUMN_NAME,
    i1.REFERENCED_TABLE_SCHEMA,i1.REFERENCED_TABLE_NAME, i1.REFERENCED_COLUMN_NAME,
    i2.UPDATE_RULE, i2.DELETE_RULE 
    FROM   
    information_schema.KEY_COLUMN_USAGE AS i1  
    INNER JOIN 
    information_schema.REFERENTIAL_CONSTRAINTS AS i2 
    ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME 
    WHERE i1.REFERENCED_TABLE_NAME IS NOT NULL  
    AND  i1.TABLE_SCHEMA  ='db_name';

membatasi kolom tertentu dalam tabel tabel

AND i1.table_name = 'target_tb_name' AND i1.column_name = 'target_col_name'
bortunac
sumber
3

Saya menulis sedikit bash onliner yang bisa Anda tulis ke skrip untuk mendapatkan hasil yang ramah:

mysql_references_to:

mysql -uUSER -pPASS -A DB_NAME -se "USE information_schema; SELECT * FROM KEY_COLUMN_USAGE WHERE REFERENCED_TABLE_NAME = '$1' AND REFERENCED_COLUMN_NAME = 'id'\G" | sed 's/^[ \t]*//;s/[ \t]*$//' |egrep "\<TABLE_NAME|\<COLUMN_NAME" |sed 's/TABLE_NAME: /./g' |sed 's/COLUMN_NAME: //g' | paste -sd "," -| tr '.' '\n' |sed 's/,$//' |sed 's/,/./'

Jadi eksekusi: mysql_references_to transaccion(di mana transaccion adalah nama tabel acak) memberikan output seperti ini:

carrito_transaccion.transaccion_id
comanda_detalle.transaccion_id
comanda_detalle_devolucion.transaccion_positiva_id
comanda_detalle_devolucion.transaccion_negativa_id
comanda_transaccion.transaccion_id
cuenta_operacion.transaccion_id
...
jhvaras
sumber
-4

Paling mudah:
1. Buka phpMyAdmin
2. Di sebelah kiri klik nama database
3. Di sudut kanan atas cari tab "Desainer"

Semua kendala akan ditampilkan di sana.

Mantas D
sumber