如何在MySQL中创建关系


96

在课堂上,我们都是“学习”数据库,每个人都在使用Access。厌倦了这一点,我试图做该类其余部分的工作,但是要使用MySQL的原始SQL命令而不是使用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(以指示谁拥有它)。


48
“我拒绝学习Access,而是学习REAL数据库引擎:MySQL”,这就是精神!祝贺= D
Metafaniel

2
请注意,外键约束不实现关系,而是实现完整性。帐户表中account_id和customer_id之间的关联实现了各个实体之间的关系。
reaanb 2015年

1
“就是这种精神!”,只要是使用InnoDB的mysql,而不是MyISAM。此外,postgreqsl在MySQL上还具有一些有趣的功能,值得一看。
jgmjgm

Answers:


102

如果表是innodb,则可以这样创建它:

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

80

正如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工具,该工具为您提供了一个使用数据库的“可视”界面。这样做的真正好处(通过Access的方法)是,通过GUI设计表之后,它向您显示了要运行的SQL,因此您可以从中学到东西。


3
您的答案是最好的解决方案
Omar 2012年

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

您必须问自己这是一对一的关系还是很多关系中的一种。也就是说,每个帐户是否都有一个客户,每个客户都有一个帐户。否则会有没有帐户的客户。您的问题暗示了后者。

如果要建立严格的一对一关系,只需合并两个表即可。

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并想要帐户信息,则可以加入customers帐户和帐户:

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

由于索引,这将是令人眼花quick乱的。

您还可以创建一个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 '18 October

11

在ehogue上添加注释,您应该使两个表上的键的大小匹配。而不是

customer_id INT( 4 ) NOT NULL ,

做了

customer_id INT( 10 ) NOT NULL ,

并确保客户表中的int列也为int(10)。


7

某些MySQL引擎支持外键。例如,InnoDB可以基于外键建立约束。如果您尝试删除一个表中有依赖项的表中的条目,则删除将失败。

如果您在MySQL中使用的表类型(例如MyISAM)不支持外键,则除了图表和查询之外,您不会链接任何表。

例如,在查询中,您可以在带有连接的select语句中链接两个表:

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

2

以下是一些有助于入门的资源:http : //www.anchor.com.au/hosting/support/CreatingAQuickMySQLRelationalDatabasehttp://code.tutsplus.com/articles/sql-for-beginners-part- 3-数据库关系--net-8561

就像其他人所说的那样,请使用GUI-尝试下载并安装Xampp(或Wamp),该Xampp在计算机上运行服务器软件(Apache和mySQL)。然后,当您在浏览器中导航到/// localhost时,选择PHPMyAdmin以直观地开始使用mySQL数据库。如上所述,使用innoDB可以根据需要建立关系。使查看您正在使用数据库表的内容变得更加容易。只需记住在完成后停止Apache和mySQL服务-它们可以打开端口,使您容易受到黑客/恶意威胁。


如果您将apache和mysql设置为仅服务本地请求,则无需停止它们。此外,如果安装这些服务,则用户至少应安装软件防火墙。话虽如此,许多家用路由器都内置有防火墙,因此,除非有人可以访问路由器,否则无论如何都不应该打开端口。
克里斯,

1

您必须知道的规则之一是,要引用的表列必须具有与“引用表”相同的数据类型。2如果您决定使用mysql,则必须使用InnoDB Engine,因为根据您的问题,该引擎支持您要在mysql中实现的功能。

贝娄是代码,请尝试一下,尽管第一批回答这个问题的人他们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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.