MySQL - 일대일 관계
MySQL 데이터베이스에서 "1 대 1" 관계를 구축하려고 합니다.예를 들어 Users 테이블과 Accounts 테이블이 있다고 가정합니다.사용자가 계정을 하나만 가질 수 있는지 확인합니다.또한 사용자당 하나의 계정만 존재할 수 있습니다.
이에 대한 두 가지 해결책을 찾았는데 무엇을 사용해야 할지 모르겠고 다른 방법이 있나요?
첫 번째 솔루션:
DROP DATABASE IF EXISTS test;
CREATE DATABASE test CHARSET = utf8 COLLATE = utf8_general_ci;
USE test;
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
user_name VARCHAR(45) NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
CREATE TABLE accounts(
id INT NOT NULL AUTO_INCREMENT,
account_name VARCHAR(45) NOT NULL,
user_id INT UNIQUE,
PRIMARY KEY(id),
FOREIGN KEY(user_id) REFERENCES users(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
이 예에서는 사용자의 프라이머리 키를 가리키는 계정의 외부 키를 정의합니다.그리고 외부 키를 고유하게 만들어서 계정에 동일한 사용자가 두 명 있을 수 없습니다.테이블을 결합하려면 다음 쿼리를 사용합니다.
SELECT * FROM users JOIN accounts ON users.id = accounts.user_id;
두 번째 솔루션:
DROP DATABASE IF EXISTS test;
CREATE DATABASE test CHARSET = utf8 COLLATE = utf8_general_ci;
USE test;
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
user_name VARCHAR(45) NOT NULL,
PRIMARY KEY(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
CREATE TABLE accounts(
id INT NOT NULL AUTO_INCREMENT,
account_name VARCHAR(45) NOT NULL,
PRIMARY KEY(id),
FOREIGN KEY(id) REFERENCES users(id)
) ENGINE = InnoDB DEFAULT CHARSET = utf8;
이 예에서는 다른 테이블의 프라이머리 키에서 프라이머리 키를 가리키는 외부 키를 만듭니다.기본 키는 기본적으로 고유하므로 이 관계는 1 대 1이 됩니다.테이블을 결합하려면 다음을 사용합니다.
SELECT * FROM users JOIN accounts ON users.id = accounts.id;
이제 질문:
- MySQL에서 일대일 관계를 만드는 가장 좋은 방법은 무엇입니까?
- 이 두 가지 외에 다른 해결 방법이 있습니까?
MySQL Workbench를 사용하고 있는데, EER 다이어그램에서 One To One 관계를 설계하고 MySQL Workbench가 SQL 코드를 생성하도록 하면 One to Many 관계가 됩니다.이것이 바로 혼란스러운 점입니다.s
이러한 솔루션 중 하나를 MySQL Workbench EER 다이어그램에 Import하면 관계가 One to Many :S로 인식됩니다.이것도 혼란스럽습니다.
그렇다면 MySQL DDL에서 일대일 관계를 정의하는 가장 좋은 방법은 무엇일까요? 이를 위해 어떤 옵션이 있습니까?
기본 키는 기본적으로 고유하므로 이 관계는 1 대 1이 됩니다.
아니요, 그러면 "1 대 0 또는 1" 관계가 됩니다.그게 정말 필요한 거야?
그렇다면 "두 번째 솔루션"이 더 좋습니다.
- 그게 더 간단해
- 스토리지 사용률 감소1(따라서 캐시가 "확장"됨)
- 관리해야2 할 지표를 줄이고 데이터 조작에 도움이 됩니다.
- 그리고 (InnoDB를 사용하고 있기 때문에) 데이터를 자연스럽게 클러스터하기 때문에 서로 가까운 사용자는 자신의 계정을 서로 가깝게 저장하게 되므로 캐시 로컬성 및 특정 범위 스캔에 도움이 될 수 있습니다.
그나저나, 넌 이 모든 걸어야 해accounts.id
통상적인 정수(자동 변환이 아님)를 지정합니다.
'아니오'의 경우 아래를 참조하십시오.
MySQL에서 일대일 관계를 만드는 가장 좋은 방법은 무엇입니까?
"best"는 오버로드된 단어이지만 "standard" 솔루션은 다른 데이터베이스와 동일합니다. 즉, 두 엔티티(사용자의 경우 사용자와 계정)를 동일한 물리적 테이블에 배치합니다.
이 두 가지 외에 다른 해결 방법이 있습니까?
이론적으로는 두 PK 간에 순환 FK를 만들 수 있지만, 안타깝게도 MySQL에서는 지원되지 않는 치킨 앤 에그 문제를 해결하려면 지연 제약이 필요합니다.
이러한 솔루션 중 하나를 MySQL Workbench EER 다이어그램에 Import하면 One to Many:S 로 인식됩니다.이것도 혼란스럽습니다.
저는 그 특별한 모델링 툴에 대한 실제 경험은 별로 없지만, 그것은 "1 대 다"라는 점에서 "많이"라는 면을 독특하게 만들어 1로 제한했기 때문이라고 생각합니다."many"는 "1 또는 many"가 아니라 "0 또는 many"를 의미하므로 "caped" 버전은 "0 또는 1"을 의미합니다.
1 추가 분야의 스토리지 비용뿐만 아니라 보조 인덱스에 대해서도 마찬가지입니다.또한 테이블을 항상 클러스터링하는 InnoDB를 사용하므로 클러스터된 테이블에서는 힙 기반 테이블보다 보조 인덱스가 훨씬 더 비싸다는 점에 유의하십시오.
2 InnoDB에는 외부 키에 대한 인덱스가 필요합니다.
은 계정 키 두 . 즉, 계정 테이블에는 후보 키 두 가 있습니다.id
★★★★★★★★★★★★★★★★★」user_id
.
따라서 저는 두 번째 접근법, 즉 외부 키를 주요 키로 사용하는 방법을 제안합니다.이것은, 다음과 같습니다.
- 하나 적은 열 사용
- 각 행을 일의로 식별할 수 있습니다.
- 계정을 사용자와 일치시킬 수 있습니다.
다음 접근방식은 어떻습니까?
테이블 사용자 생성
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
한 을 만듭니다.
user_id
★★★★★★★★★★★★★★★★★」account_id
키및를 "/"로 합니다.user_id and account_id
CREATE TABLE `account` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
테이블 user2 계정 만들기
CREATE TABLE `user2account` ( `user_id` int(11) NOT NULL, `account_id` int(11) NOT NULL, PRIMARY KEY (`user_id`,`account_id`), UNIQUE KEY `FK_account_idx` (`account_id`), UNIQUE KEY `FK_user_idx` (`user_id`), CONSTRAINT `FK_account` FOREIGN KEY (`account_id`) REFERENCES `account` (`id`), CONSTRAINT `FK_user` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
이 솔루션은 데이터베이스에서 설치 공간이 가장 크지만 몇 가지 이점이 있습니다.
- FK_Key를 사용자 테이블 또는 계정 테이블에 넣는 것은 1대 다의 관련성을 기대할 수 있습니다(사용자는 많은 계정을 가지고 있습니다).
- 은 ★★★★★★에 비해,
user2account
하기 위해 되며, 다대다에 고유 합니다.user_id
등에 대하여account_id
일대일 관계 이외의 것을 만들지 않도록 합니다.
이 솔루션에서 알 수 있는 주요 장점은 회사 내 다른 코드 레이어 또는 부서로 작업을 분할할 수 있다는 것입니다.
- 사용자 생성은 A부문이 담당합니다.계정 테이블에 대한 쓰기 권한이 없어도 가능합니다.
- B부문은 계정을 만듭니다.이것은 사용자 테이블에 대한 쓰기 권한이 없어도 가능합니다.
- 매핑 작성은 부문 C에서 담당합니다.사용자 또는 계정 테이블에 대한 쓰기 권한이 없어도 가능합니다.
- 부문 C가 매핑을 작성하면 부문 C에 먼저 매핑 삭제를 요구하지 않으면 부문 A 또는 B에 의해 사용자도 계정도 삭제할 수 없습니다.
언급URL : https://stackoverflow.com/questions/13644979/mysql-one-to-one-relationship
'programing' 카테고리의 다른 글
php의 플로트 비교 (0) | 2022.12.27 |
---|---|
Javascript에서 난수 생성기 시드하기 (0) | 2022.12.27 |
json_encode/json_decode - PHP의 어레이 대신 stdClass를 반환합니다. (0) | 2022.12.27 |
Hamcrest 비교 컬렉션 (0) | 2022.12.07 |
이름, 성, 시에서 보낸 이메일 목록을 작성하려면 어떻게 해야 합니까? (0) | 2022.12.07 |