Cách tạo mối quan hệ trong MySQL


96

Trong lớp, tất cả chúng tôi đang 'nghiên cứu' cơ sở dữ liệu và mọi người đều đang sử dụng Access. Chán với điều này, tôi đang cố gắng làm những gì phần còn lại của lớp đang làm, nhưng với các lệnh SQL thô với MySQL thay vì sử dụng Access.

Tôi đã quản lý để tạo cơ sở dữ liệu và bảng, nhưng bây giờ làm cách nào để tạo mối quan hệ giữa hai bảng?

Nếu tôi có hai bảng như thế này:

CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY ( account_id )
)

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
    PRIMARY KEY ( customer_id )
)

Làm cách nào để tạo 'mối quan hệ' giữa hai bảng? Tôi muốn mỗi tài khoản được 'gán' một customer_id (để cho biết ai sở hữu nó).


48
"TÔI TỪ CHỐI học Access, tôi sẽ nghiên cứu một công cụ cơ sở dữ liệu THỰC: MySQL" Đó là tinh thần! Xin chúc mừng = D
Metafaniel

2
Lưu ý rằng các ràng buộc khóa ngoại không triển khai các mối quan hệ, chúng thực hiện tính toàn vẹn. Sự liên kết giữa account_id và customer_id trong bảng tài khoản thực hiện mối quan hệ giữa các thực thể tương ứng.
reaanb

1
"Đó là tinh thần!", Miễn là nó là mysql với InnoDB, không phải MyISAM. Ngoài ra postgreqsl có một vài tính năng thú vị trên MySQL đáng xem xét.
jgmjgm

Câu trả lời:


102

Nếu các bảng là innodb, bạn có thể tạo nó như sau:

CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY ( account_id ), 
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 
) ENGINE=INNODB;

Bạn phải chỉ định rằng các bảng là innodb vì myisam engine không hỗ trợ khóa ngoại. Nhìn vào đây để biết thêm thông tin.


Tôi đã thấy trong một bài báo, rằng không cần chỉ định mệnh đề ENGINE = InnoDB nếu InnoDB được định nghĩa là công cụ lưu trữ mặc định, có thể kiểm tra bằng lệnh (mysql> SELECT @@ default_storage_engine;)
Arun

80

như ehogue đã nói, hãy đặt cái này vào TẠO BẢNG

FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 

cách khác, nếu bạn đã tạo bảng, hãy sử dụng lệnh ALTER TABLE:

ALTER TABLE `accounts`
  ADD CONSTRAINT `FK_myKey` FOREIGN KEY (`customer_id`) REFERENCES `customers` (`customer_id`) ON DELETE CASCADE ON UPDATE CASCADE;

Một cách tốt để bắt đầu học các lệnh này là sử dụng MySQL GUI Tools , cung cấp cho bạn giao diện "trực quan" hơn để làm việc với cơ sở dữ liệu của bạn. Lợi ích thực sự của điều đó (so với phương pháp của Access) là sau khi thiết kế bảng của bạn thông qua GUI, nó hiển thị cho bạn SQL mà nó sẽ chạy và do đó bạn có thể học hỏi từ đó.


3
Câu trả lời của bạn là giải pháp tốt nhất
Omar

14
CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY ( account_id )
)

and

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
)

How do I create a 'relationship' between the two tables? I want each account to be 'assigned' one customer_id (to indicate who owns it).

Bạn phải tự hỏi mình rằng đây là mối quan hệ 1-1 hay mối quan hệ có 1 không 2. Tức là mọi tài khoản đều có khách hàng và mọi khách hàng đều có tài khoản. Hoặc sẽ có những khách hàng không có tài khoản. Câu hỏi của bạn ngụ ý sau.

Nếu bạn muốn có mối quan hệ 1-1 nghiêm ngặt, chỉ cần hợp nhất hai bảng.

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
)

Trong trường hợp khác, cách chính xác để tạo mối quan hệ giữa hai bảng là tạo một bảng quan hệ.

CREATE TABLE customersaccounts(
    customer_id INT NOT NULL,
    account_id INT NOT NULL,
    PRIMARY KEY (customer_id, account_id)
    FOREIGN KEY customer_id references customers (customer_id) on delete cascade,
    FOREIGN KEY account_id  references accounts  (account_id) on delete cascade
}

Sau đó, nếu bạn có customer_id và muốn có thông tin tài khoản, bạn tham gia trên các tài khoản và tài khoản khách hàng:

SELECT a.*
    FROM customersaccounts ca
        INNER JOIN accounts a ca.account_id=a.account_id
            AND ca.customer_id=mycustomerid;

Bởi vì việc lập chỉ mục này sẽ rất nhanh chóng.

Bạn cũng có thể tạo CHẾ ĐỘ XEM để tạo cho bạn hiệu ứng của bảng tài khoản khách hàng được kết hợp trong khi vẫn tách chúng ra

CREATE VIEW customeraccounts AS 
    SELECT a.*, c.* FROM customersaccounts ca
        INNER JOIN accounts a ON ca.account_id=a.account_id
        INNER JOIN customers c ON ca.customer_id=c.customer_id;

1
Tôi nghĩ ý bạn là ca.không ac.(3 chỗ).
Chế độ xem hình elip

bạn đã viết PRIMARY KEY (customer_id, account_id)không có dấu phẩy sau nó
theonlygusti

11

Thêm vào nhận xét của ehogue, bạn nên làm cho kích thước của các phím trên cả hai bảng phù hợp. Thay vì

customer_id INT( 4 ) NOT NULL ,

làm cho nó

customer_id INT( 10 ) NOT NULL ,

và đảm bảo rằng cột int của bạn trong bảng khách hàng cũng là int (10).


7

Một số công cụ MySQL hỗ trợ khóa ngoại. Ví dụ, InnoDB có thể thiết lập các ràng buộc dựa trên các khóa ngoại. Nếu bạn cố gắng xóa một mục nhập trong một bảng có các thành phần phụ thuộc trong bảng khác, quá trình xóa sẽ không thành công.

Nếu bạn đang sử dụng loại bảng trong MySQL, chẳng hạn như MyISAM, không hỗ trợ khóa ngoại, bạn không liên kết các bảng ở bất kỳ đâu ngoại trừ sơ đồ và truy vấn của mình.

Ví dụ: trong một truy vấn, bạn liên kết hai bảng trong một câu lệnh chọn với một phép nối:

SELECT a, b from table1 LEFT JOIN table2 USING (common_field);

2

Dưới đây là một số tài nguyên sẽ giúp bắt đầu: http://www.anchor.com.au/hosting/support/CreatingAQuickMySQLRelationalDatabasehttp://code.tutsplus.com/articles/sql-for-beginners-part- 3-cơ sở dữ liệu-mối quan hệ - net-8561

Cũng như những người khác đã nói, hãy sử dụng GUI - hãy thử tải xuống và cài đặt Xampp (hoặc Wamp) chạy phần mềm máy chủ (Apache và mySQL) trên máy tính của bạn. Sau đó, khi bạn điều hướng đến // localhost trong trình duyệt, hãy chọn PHPMyAdmin để bắt đầu làm việc trực quan với cơ sở dữ liệu mySQL. Như đã đề cập ở trên, innoDB được sử dụng để cho phép bạn tạo mối quan hệ như bạn yêu cầu. Giúp cho việc xem bạn đang làm gì với các bảng cơ sở dữ liệu dễ dàng hơn. Chỉ cần nhớ DỪNG các dịch vụ Apache và mySQL khi hoàn tất - những dịch vụ này có thể mở ra các cổng có thể khiến bạn gặp phải các mối đe dọa tấn công / độc hại.


Nếu bạn thiết lập apache và mysql để chỉ phục vụ các yêu cầu cục bộ thì bạn không cần phải dừng chúng. Bên cạnh đó, người dùng nên cài đặt ít nhất một tường lửa phần mềm nếu cài đặt các loại dịch vụ này. Như đã nói, nhiều bộ định tuyến gia đình đi kèm với một bức tường lửa được tích hợp sẵn, vì vậy các cổng không nên mở, trừ khi chúng đã được ai đó có quyền truy cập vào bộ định tuyến mở.
Chris

1

Một trong những quy tắc bạn phải biết là cột bảng mà bạn muốn tham chiếu đến phải có cùng kiểu dữ liệu với Bảng tham chiếu. 2 nếu bạn quyết định sử dụng mysql, bạn phải sử dụng InnoDB Engine vì theo câu hỏi của bạn đó là engine hỗ trợ những gì bạn muốn đạt được trong mysql.

Dưới đây là mã hãy thử nó mặc dù những người đầu tiên trả lời câu hỏi này, họ 100% cung cấp câu trả lời tuyệt vời và vui lòng xem xét tất cả.

CREATE TABLE accounts(
    account_id INT NOT NULL AUTO_INCREMENT,
    customer_id INT( 4 ) NOT NULL ,
    account_type ENUM( 'savings', 'credit' ) NOT NULL,
    balance FLOAT( 9 ) NOT NULL,
    PRIMARY KEY (account_id)
)ENGINE=InnoDB;

CREATE TABLE customers(
    customer_id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(20) NOT NULL,
    address VARCHAR(20) NOT NULL,
    city VARCHAR(20) NOT NULL,
    state VARCHAR(20) NOT NULL,
     PRIMARY KEY ( account_id ), 
FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 
)ENGINE=InnoDB; 

0
create table departement(
    dep_id      int primary key auto_increment,
    dep_name    varchar(100) not null,
    dep_descriptin      text,
    dep_photo       varchar(100) not null,
    dep_video       varchar(300) not null
);

create table newsfeeds(
    news_id         int primary key auto_increment,
    news_title      varchar(200) not null,
    news_description    text,
    news_photo          varchar(300) ,
    news_date           varchar(30) not null,
    news_video          varchar(300),
    news_comment        varchar(200),
    news_departement    int foreign key(dep_id) references departement(dep_id)
);

Vui lòng cung cấp một số giải thích trên lược đồ bạn đã cung cấp.
samabcde
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.