Làm cách nào để xem tất cả các khóa ngoại vào bảng hoặc cột?


Câu trả lời:


764

Đối với một bảng:

SELECT 
  TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
FROM
  INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_SCHEMA = '<database>' AND
  REFERENCED_TABLE_NAME = '<table>';

Đối với một cột:

SELECT 
  TABLE_NAME,COLUMN_NAME,CONSTRAINT_NAME, REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME
FROM
  INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
  REFERENCED_TABLE_SCHEMA = '<database>' AND
  REFERENCED_TABLE_NAME = '<table>' AND
  REFERENCED_COLUMN_NAME = '<column>';

Về cơ bản, chúng tôi đã thay đổi REAXENCED_TABLE_NAME bằng REFERENCED_COLUMN_NAME trong mệnh đề where.


26
điều này luôn mang lại cho tôi một tập hợp trống, trong khi truy vấn được đề xuất bởi Node bên dưới hoạt động tốt
Acute

7
@Acute: Bạn có chắc là bạn đang hỏi về bảng đúng không? Nếu truy vấn của Node hoạt động, thì có khả năng bạn sẽ hỏi về hướng khác (nghĩa là các khóa TỪ mytable, không phải các khóa TO mytable.) Điều này hy vọng bạn đã viết '<bảng>' với tên bảng và không có '<' và '>' ?
Vinko Vrsalovic

3
Có vẻ như tôi đã hiểu nhầm truy vấn của bạn, vì tôi đang truy vấn các khóa tham chiếu TỪ <bảng> :) (vâng, tôi đã viết tên bảng thay vì "<bảng>" XD)
Cấp tính

4
Trừ khi bạn chắc chắn tên bảng của bạn là duy nhất, có lẽ bạn cũng muốn hạn chế truy vấn của mình vào một cơ sở dữ liệu cụ thể. Thay đổi mệnh đề where thành:where REFERENCED_TABLE_SCHEMA = 'mydatabase' and REFERENCED_TABLE_NAME = 'mytable'
user12345

Điều này sẽ không hoạt động trong trường hợp người dùng không root mặc dù người dùng có tất cả các quyền đối với cơ sở dữ liệu
Deepak Ram

275

EDIT: Như đã chỉ ra trong các bình luận, đây không phải là câu trả lời chính xác cho câu hỏi OP, nhưng thật hữu ích khi biết lệnh này. Câu hỏi này xuất hiện trên Google cho những gì tôi đang tìm kiếm và hình dung tôi sẽ để lại câu trả lời này cho những người khác tìm thấy.

SHOW CREATE TABLE `<yourtable>`;

Tôi tìm thấy câu trả lời này ở đây: MySQL: hiển thị các ràng buộc trên lệnh bảng

Tôi cần theo cách này vì tôi muốn xem FK hoạt động như thế nào, thay vì chỉ xem nó có tồn tại hay không.


37
Điều này cho thấy tất cả các ràng buộc trong <yourtable>, không phải tất cả các ràng buộc trỏ đến <yourtable>.
Barmar

18
Như @Barmar nói, điều này hoàn toàn sai; nó sẽ hiển thị các phím nước ngoài thuộc các bảng định, nhưng sẽ không hiển thị các phím nước ngoài chỉ ĐẾN bảng, đó là những gì các câu hỏi yêu cầu. Không biết làm thế nào điều này có 50 upvote; Tôi đoán mọi người đã kết thúc ở đây khi họ thực sự tìm kiếm câu trả lời cho câu hỏi ngược lại, dù sao cũng tìm thấy câu trả lời của họ và không buồn đọc câu hỏi ban đầu (hoặc thậm chí là tiêu đề của nó) trước khi nâng cấp.
Đánh dấu Amery

2
@MarkAmery: đây là kết quả đầu tiên của display foreign keys mysqlgoogle, có thể đó là lý do tại sao;)
Jigar

1
thisi thực sự hiển thị tất cả các ràng buộc tồn tại, phpmyadmin sẽ chỉ hiển thị cho bạn cái chỉ vào bảng của bạn. có vẻ đủ tốt để tránh trùng lặp với công cụ ORM
william.eyidi

3
Đây là những gì tôi đang tìm kiếm, vì vậy cảm ơn bạn đã đăng nó mặc dù nó không trả lời câu hỏi của OP. Không bao giờ đau đớn để biết làm thế nào để nhìn theo cả hai hướng trong một mối quan hệ!
Charles Wood

75

Nếu bạn sử dụng InnoDB và FK được xác định, bạn có thể truy vấn cơ sở dữ liệu information_schema, vd:

SELECT * FROM information_schema.TABLE_CONSTRAINTS 
WHERE information_schema.TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'FOREIGN KEY' 
AND information_schema.TABLE_CONSTRAINTS.TABLE_SCHEMA = 'myschema'
AND information_schema.TABLE_CONSTRAINTS.TABLE_NAME = 'mytable';

15
Thật ra, điều đó chỉ sai hướng. truy vấn đó hiển thị tất cả các khóa ngoại trỏ TỪ 'mytable', không phải tất cả các khóa ngoại chỉ vào 'mytable'.
Christian Oudard

1
Điều này làm việc tốt hơn trong trường hợp của tôi. Tôi cần bỏ mọi ràng buộc khóa ngoại (và chỉ những ràng buộc) khỏi một bảng để có thể thay đổi công cụ InnoDB MyISAM hoặc NDB.
Kohányi Róbert

Bạn có thể nhận được các khóa ngoại theo cả hai hướng từ bảng REAXENTIAL_CONSTRAINTS - Tôi đã thêm một câu trả lời khác với truy vấn.
ChrisV

45

Đăng một câu trả lời cũ để thêm một số thông tin hữu ích.

Tôi đã gặp một vấn đề tương tự, nhưng tôi cũng muốn thấy CONSTRAINT_TYPE cùng với tên bảng và cột TÀI LIỆU THAM KHẢO. Vì thế,

  1. Để xem tất cả các FK trong bảng của bạn:

    USE '<yourschema>';
    
    SELECT i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME 
    FROM information_schema.TABLE_CONSTRAINTS i 
    LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME 
    WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY' 
    AND i.TABLE_SCHEMA = DATABASE()
    AND i.TABLE_NAME = '<yourtable>';
  2. Để xem tất cả các bảng và FK trong lược đồ của bạn:

    USE '<yourschema>';
    
    SELECT i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME 
    FROM information_schema.TABLE_CONSTRAINTS i 
    LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME 
    WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY' 
    AND i.TABLE_SCHEMA = DATABASE();
  3. Để xem tất cả các FK trong cơ sở dữ liệu của bạn:

    SELECT i.TABLE_SCHEMA, i.TABLE_NAME, i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME 
    FROM information_schema.TABLE_CONSTRAINTS i 
    LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME 
    WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY';

Nhớ lại!

Đây là sử dụng công cụ lưu trữ InnoDB. Nếu bạn dường như không thể nhận được bất kỳ khóa ngoại nào để hiển thị sau khi thêm chúng, có thể là do các bảng của bạn đang sử dụng MyISAM.

Để kiểm tra:

SELECT * TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = '<yourschema>';

Để khắc phục, sử dụng điều này:

ALTER TABLE `<yourtable>` ENGINE=InnoDB;

8
Các truy vấn đó chạy nhanh hơn nhiều (từ 2 giây đến 0,0015 giây) nếu bạn chỉ định k.TABLE_SCHema = DATABASE () và k.TABLE_NAME = '<bảng>' trên mệnh đề WHERE, như được ghi lại ở đây dev.mysql.com/doc/refman /5.5/en/...
guigouz

2
câu trả lời chính xác. Bạn có giải pháp nào cho MyISAM không?
Beau Bouchard

2
Thật không may, MyISAM không hỗ trợ khóa ngoại. dev.mysql.com/doc/refman/5.7/en/myisam-st Storage
Andy

24

Thay thế cho câu trả lời của Node, nếu bạn sử dụng InnoDB và FK được xác định, bạn có thể truy vấn cơ sở dữ liệu information_schema, ví dụ:

SELECT CONSTRAINT_NAME, TABLE_NAME, REFERENCED_TABLE_NAME
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = '<schema>'
AND TABLE_NAME = '<table>'

cho các khóa ngoại từ <bảng> hoặc

SELECT CONSTRAINT_NAME, TABLE_NAME, REFERENCED_TABLE_NAME
FROM information_schema.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_SCHEMA = '<schema>'
AND REFERENCED_TABLE_NAME = '<table>'

cho các khóa ngoại vào <bảng>

Bạn cũng có thể nhận được UPDATE_RULE và DELETE_RULE nếu bạn muốn chúng.


2
Cá nhân tôi thích câu trả lời này vì sử dụng bảng REAXENTIAL_CONSTRAINTS cung cấp cho bạn quy tắc cập nhật và xếp tầng. +1
Luke Madhanga

Khám phá về một bảng bạn không nên quên rằng các khóa ngoại có thể được thiết lập cả hai cách!
Bộ mã hóa

11

Giải pháp này sẽ không chỉ hiển thị tất cả các mối quan hệ mà còn cả tên ràng buộc, được yêu cầu trong một số trường hợp (ví dụ: chống hạn chế):

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;

Nếu bạn muốn kiểm tra các bảng trong cơ sở dữ liệu cụ thể, ở cuối truy vấn, hãy thêm tên lược đồ:

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
    and table_schema = 'database_name';

Tương tự, đối với một tên cột cụ thể, thêm

và tên_bảng = 'tên_bảng

ở cuối truy vấn

Lấy cảm hứng từ bài viết này ở đây


7

Sử dụng REAXENCED_TABLE_NAME không phải lúc nào cũng hoạt động và có thể là giá trị NULL. Các truy vấn sau đây có thể hoạt động thay thế:

select * from INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = '<table>';

4

Cách nhanh chóng để liệt kê FK của bạn (tham chiếu Khóa ngoài) bằng cách sử dụng

KEY_COLUMN_USAGE view:

SELECT CONCAT( table_name, '.',
column_name, ' -> ',
referenced_table_name, '.',
referenced_column_name ) AS list_of_fks
FROM information_schema.KEY_COLUMN_USAGE
WHERE REFERENCED_TABLE_SCHEMA = (your schema name here)
AND REFERENCED_TABLE_NAME is not null
ORDER BY TABLE_NAME, COLUMN_NAME;

Truy vấn này giả định rằng các ràng buộc và tất cả các bảng tham chiếu và tham chiếu nằm trong cùng một lược đồ.

Thêm bình luận của riêng bạn.

Nguồn: hướng dẫn sử dụng mysql chính thức.


3

Giải pháp tôi đưa ra rất mong manh; nó dựa vào quy ước đặt tên của django cho các khóa ngoại.

USE information_schema;
tee mysql_output
SELECT * FROM TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_SCHEMA = 'database_name';
notee

Sau đó, trong vỏ,

grep 'refs_tablename_id' mysql_output

2

Để tìm tất cả các bảng có chứa một khóa ngoại cụ thể, chẳng hạn nhưemployee_id

SELECT DISTINCT TABLE_NAME 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME IN ('employee_id')
AND TABLE_SCHEMA='table_name';

2

Nếu bạn cũng muốn lấy tên của cột khóa ngoại:

SELECT i.TABLE_SCHEMA, i.TABLE_NAME, 
       i.CONSTRAINT_TYPE, i.CONSTRAINT_NAME, 
       k.COLUMN_NAME, k.REFERENCED_TABLE_NAME, k.REFERENCED_COLUMN_NAME 
  FROM information_schema.TABLE_CONSTRAINTS i 
  LEFT JOIN information_schema.KEY_COLUMN_USAGE k 
       ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME 
 WHERE i.TABLE_SCHEMA = '<TABLE_NAME>' AND i.CONSTRAINT_TYPE = 'FOREIGN KEY' 
 ORDER BY i.TABLE_NAME;

Cảm ơn giải pháp tuyệt vời! Tôi cũng cần tên cột, để thêm tên: 'k.COLUMN_NAME'
Andreas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.