วิธีสร้างความสัมพันธ์ใน MySQL


98

ในชั้นเรียนเราทุกคนกำลัง 'ศึกษา' ฐานข้อมูลและทุกคนใช้ Access เบื่อกับสิ่งนี้ฉันกำลังพยายามทำในสิ่งที่คลาสอื่น ๆ กำลังทำอยู่ แต่ใช้คำสั่ง SQL ดิบกับ MySQL แทนการใช้ Access

ฉันจัดการสร้างฐานข้อมูลและตารางแล้ว แต่ตอนนี้ฉันจะสร้างความสัมพันธ์ระหว่างสองตารางได้อย่างไร

ถ้าฉันมีสองตารางของฉันแบบนี้:

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 )
)

ฉันจะสร้าง 'ความสัมพันธ์' ระหว่างสองตารางได้อย่างไร? ฉันต้องการให้แต่ละบัญชี 'กำหนด' customer_id หนึ่งบัญชี (เพื่อระบุว่าใครเป็นเจ้าของ)


49
"ฉันปฏิเสธที่จะศึกษา Access ฉันจะศึกษาเครื่องมือฐานข้อมูล REAL: MySQL" นั่นคือจิตวิญญาณ! ขอแสดงความยินดี = D
Metafaniel

2
โปรดทราบว่าข้อ จำกัด ของคีย์ต่างประเทศไม่ได้ใช้ความสัมพันธ์ แต่จะใช้ความสมบูรณ์ การเชื่อมโยงระหว่าง account_id และ customer_id ในตารางบัญชีใช้ความสัมพันธ์ระหว่างเอนทิตีที่เกี่ยวข้อง
reaanb

1
"นั่นคือวิญญาณ!" ตราบใดที่เป็น mysql กับ InnoDB ไม่ใช่ MyISAM นอกจากนี้ postgreqsl ยังมีคุณสมบัติที่น่าสนใจบางอย่างเหนือ MySQL ที่น่าสนใจ
jgmjgm

คำตอบ:


104

หากตารางเป็นสิ่งที่ไม่ดีคุณสามารถสร้างได้ดังนี้:

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;

คุณต้องระบุว่าตารางเป็น Innodb เนื่องจากเอ็นจิ้น myisam ไม่รองรับคีย์ต่างประเทศ ดูที่นี่สำหรับข้อมูลเพิ่มเติม


ฉันเห็นในบทความว่าไม่จำเป็นต้องระบุส่วนคำสั่ง ENGINE = InnoDB ถ้า InnoDB ถูกกำหนดให้เป็นเครื่องมือจัดเก็บข้อมูลเริ่มต้นสามารถตรวจสอบโดยใช้คำสั่ง (mysql> SELECT @@ default_storage_engine;)
อรุณ

81

ตามที่คุณ ehogue บอกใส่สิ่งนี้ไว้ใน CREATE TABLE ของคุณ

FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 

หรือถ้าคุณสร้างตารางไว้แล้วให้ใช้คำสั่ง ALTER TABLE:

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

วิธีที่ดีวิธีหนึ่งในการเริ่มเรียนรู้คำสั่งเหล่านี้คือการใช้MySQL GUI Toolsซึ่งให้อินเทอร์เฟซที่เป็น "ภาพ" มากขึ้นสำหรับการทำงานกับฐานข้อมูลของคุณ ประโยชน์ที่แท้จริงของสิ่งนั้น (เหนือวิธีการของ Access) คือหลังจากออกแบบตารางของคุณผ่าน GUI แล้วจะแสดงให้คุณเห็นว่า SQL กำลังจะทำงานดังนั้นคุณสามารถเรียนรู้จากสิ่งนั้นได้


3
คำตอบของคุณคือทางออกที่ดีที่สุด
Omar

15
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).

คุณต้องถามตัวเองว่านี่คือความสัมพันธ์แบบ 1 ต่อ 1 หรือ 1 จากความสัมพันธ์มากมาย นั่นคือทุกบัญชีมีลูกค้าหรือไม่และลูกค้าทุกคนมีบัญชี หรือจะมีลูกค้าที่ไม่มีบัญชี คำถามของคุณมีนัยอย่างหลัง

หากคุณต้องการมีความสัมพันธ์แบบ 1 ต่อ 1 ที่เข้มงวดเพียงแค่รวมสองตาราง

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,
)

ในอีกกรณีหนึ่งวิธีที่ถูกต้องในการสร้างความสัมพันธ์ระหว่างสองตารางคือการสร้างตารางความสัมพันธ์

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
}

จากนั้นหากคุณมี customer_id และต้องการข้อมูลบัญชีคุณจะเข้าร่วมในบัญชีลูกค้าและบัญชี:

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

เนื่องจากการจัดทำดัชนีนี้จะรวดเร็วอย่างไม่น่าเชื่อ

คุณยังสามารถสร้าง VIEW ซึ่งให้ผลของตารางบัญชีลูกค้ารวมกันในขณะที่แยกพวกเขาออกจากกัน

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
ฉันคิดว่าคุณca.ไม่ได้หมายถึงac.(3 ที่)
มุมมองรูปไข่

คุณเขียนPRIMARY KEY (customer_id, account_id)โดยไม่มีลูกน้ำตามหลัง
theonlygusti

11

การเพิ่มความคิดเห็นโดย ehogue คุณควรกำหนดขนาดของปุ่มบนทั้งสองตารางให้ตรงกัน ค่อนข้างมากกว่า

customer_id INT( 4 ) NOT NULL ,

ทำมัน

customer_id INT( 10 ) NOT NULL ,

และตรวจสอบให้แน่ใจว่าคอลัมน์ int ของคุณในตารางลูกค้าเป็น int (10) ด้วย


7

เอ็นจิ้น MySQL บางตัวรองรับคีย์ต่างประเทศ ตัวอย่างเช่น InnoDB สามารถสร้างข้อ จำกัด ตามคีย์ต่างประเทศ หากคุณพยายามลบรายการในตารางหนึ่งที่มีผู้อ้างอิงอยู่ในอีกตารางหนึ่งการลบจะล้มเหลว

หากคุณใช้ประเภทตารางใน MySQL เช่น MyISAM ที่ไม่รองรับคีย์ต่างประเทศคุณจะไม่เชื่อมโยงตารางใด ๆ ยกเว้นไดอะแกรมและคิวรีของคุณ

ตัวอย่างเช่นในแบบสอบถามคุณเชื่อมโยงตารางสองตารางในคำสั่งเลือกด้วยการเข้าร่วม:

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

2

นี่คือแหล่งข้อมูลสองสามอย่างที่จะช่วยในการเริ่มต้น: http://www.anchor.com.au/hosting/support/CreatingAQuickMySQLRelationalDatabaseและhttp://code.tutsplus.com/articles/sql-for-beginners-part- 3- ฐานข้อมูล - ความสัมพันธ์ - net-8561

เช่นเดียวกับที่คนอื่นพูดให้ใช้ GUI - ลองดาวน์โหลดและติดตั้ง Xampp (หรือ Wamp) ซึ่งเรียกใช้ซอฟต์แวร์เซิร์ฟเวอร์ (Apache และ mySQL) บนคอมพิวเตอร์ของคุณ จากนั้นเมื่อคุณไปที่ // localhost ในเบราว์เซอร์ให้เลือก PHPMyAdmin เพื่อเริ่มทำงานกับฐานข้อมูล mySQL ด้วยสายตา ดังที่ได้กล่าวมาแล้วใช้ innoDB เพื่อให้คุณสร้างความสัมพันธ์ตามที่คุณร้องขอ ทำให้ฮีปง่ายขึ้นเพื่อดูว่าคุณกำลังทำอะไรกับตารางฐานข้อมูล อย่าลืมหยุดบริการ Apache และ mySQL เมื่อเสร็จสิ้นสิ่งเหล่านี้สามารถเปิดพอร์ตซึ่งอาจทำให้คุณถูกแฮ็ก / ภัยคุกคามที่เป็นอันตราย


หากคุณตั้งค่า apache และ mysql เพื่อให้บริการเฉพาะคำขอในพื้นที่คุณก็ไม่จำเป็นต้องหยุด นอกจากนี้ผู้ใช้ควรมีซอฟต์แวร์ไฟร์วอลล์ติดตั้งอย่างน้อยที่สุดหากติดตั้งบริการประเภทนี้ ด้วยเหตุนี้เราเตอร์ในบ้านจำนวนมากจึงมาพร้อมกับไฟร์วอลล์ในตัวดังนั้นพอร์ตจึงไม่ควรเปิดอยู่แล้วเว้นแต่จะมีการเปิดโดยผู้ที่สามารถเข้าถึงเราเตอร์ได้
คริส

1

กฎข้อหนึ่งที่คุณต้องรู้คือคอลัมน์ของตารางที่คุณต้องการอ้างอิงจะต้องเป็นชนิดข้อมูลเดียวกับตารางอ้างอิง 2 หากคุณตัดสินใจใช้ mysql คุณต้องใช้ InnoDB Engine เพราะตามคำถามของคุณนั่นคือเอ็นจิ้นที่รองรับสิ่งที่คุณต้องการบรรลุใน mysql

Bellow เป็นรหัสที่ลองใช้แม้ว่าคนกลุ่มแรกที่ตอบคำถามนี้พวกเขา 100% ให้คำตอบที่ดีเยี่ยมและโปรดพิจารณาพวกเขาทั้งหมด

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)
);

โปรดให้คำอธิบายเกี่ยวกับสคีมาที่คุณให้มา
samabcde
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.