MySQL에서 관계를 만드는 방법


97

수업 시간에 우리는 모두 데이터베이스를 '연구'하고 있으며 모두가 Access를 사용하고 있습니다. 이것에 지겨워 나머지 클래스가하는 일을 시도하고 있지만 Access를 사용하는 대신 MySQL을 사용하여 원시 SQL 명령을 사용합니다.

데이터베이스와 테이블을 만들 수 있었지만 이제 어떻게 두 테이블 간의 관계를 만들 수 있습니까?

다음과 같은 두 개의 테이블이있는 경우 :

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 연구를 거부합니다. 실제 데이터베이스 엔진 인 MySQL을 연구하겠습니다."그게 바로 정신입니다! 축하합니다 = D
Metafaniel 2015-08-24

2
외래 키 제약 조건은 관계를 구현하지 않고 무결성을 구현합니다. accounts 테이블에서 account_id와 customer_id 간의 연관은 각 엔티티 간의 관계를 구현합니다.
reaanb

1
MyISAM이 아니라 InnoDB를 사용하는 mysql이라면 "그게 바로 정신이야!" 또한 postgreqsl에는 살펴볼 가치가있는 MySQL에 비해 몇 가지 흥미로운 기능이 있습니다.
jgmjgm

답변:


103

테이블이 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;

myisam 엔진은 외래 키를 지원하지 않기 때문에 테이블이 innodb임을 지정해야합니다. 봐 여기에 대한 추가 정보를 원하시면.


기사에서 InnoDB가 기본 스토리지 엔진으로 정의되어 있으면 ENGINE = InnoDB 절을 지정할 필요가 없으며 명령을 사용하여 확인할 수 있습니다 (mysql> SELECT @@ default_storage_engine;)
Arun

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
당신의 대답은 최고의 솔루션입니다
오마르

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가 있고 계정 정보가 필요한 경우 customersaccounts 및 계정에 가입합니다.

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

인덱싱 때문에 이것은 눈부시게 빠를 것입니다.

결합 된 customersaccounts 테이블의 효과를 제공하는 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 ,

customers 테이블의 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를 사용하십시오-컴퓨터에서 서버 소프트웨어 (Apache 및 mySQL)를 실행하는 Xampp (또는 Wamp)를 다운로드하여 설치해보십시오. 그런 다음 브라우저에서 // localhost로 이동하면 PHPMyAdmin을 선택하여 mySQL 데이터베이스 작업을 시각적으로 시작합니다. 위에서 언급했듯이 innoDB를 사용하여 요청한대로 관계를 만들 수 있습니다. 데이터베이스 테이블로 수행중인 작업을 힙에서 더 쉽게 볼 수 있습니다. 완료되면 Apache 및 mySQL 서비스를 중지하는 것을 잊지 마십시오. 이러한 서비스는 해킹 / 악의적 인 위협에 노출 될 수있는 포트를 열 수 있습니다.


apache와 mysql을 설정하여 로컬 요청 만 처리하면 중지 할 필요가 없습니다. 이러한 종류의 서비스를 설치하는 경우 사용자는 최소한 소프트웨어 방화벽을 설치해야합니다. 즉, 많은 홈 라우터에는 방화벽이 내장되어 있으므로 라우터에 액세스 할 수있는 누군가가 포트를 열지 않는 한 포트를 열어서는 안됩니다.
Chris

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.