The Ultimate MySQL Bootcamp 14강을 공부하며 정리한 내용입니다.
만들면서 헷갈리는 부분들이 많았는데, 테이블간의 관계를 생각하면서 만들었다. 그런데, 강사님이 만든 스키마를 보고 새롭게 알게된 내용이 있어서 정리해보려고 한다.
테이블은 오직 하나의 기본키를 가질 수 있다고 했는데, 아래의 코드를 보면 likes 테이블에서는 PRIMARY KEY(photo_id, tag_id)
와 같이 설정했다. likes 테이블은 기본키를 2개 가지는 걸까?
결론부터 말하자면, 기본키가 2개라는 뜻이 아니라 두 개의 칼럼으로 하나의 기본키를 만드는 것이다.
기본키를 2개 설정하면 다음과 같은 에러가 발생한다.
likes 테이블은 다음과 같다. likes 테이블은 하나의 기본키를 갖는데, user_id
와 photo_id
가 각각 고유해야하는 것이 아니라 이 둘을 한 쌍으로 봤을때, 고유해야한다는 것이다. 즉, user_id=1, photo_id=1
인 데이터가 있을 수 있고, user_id=1, photo_id=2
인 데이터가 있을 수 있지만, user_id=1, photo_id=1
인 데이터를 추가하려고 하면, 다음과 같은 에러가 발생한다.
따라서, 두 개의 칼럼을 하나의 기본키로 가질 수 있고, 이것을 복합키라고 한다. 두개의 칼럼을 기본키로 설정하는 것과는 다르다.
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE photos (
id INT AUTO_INCREMENT PRIMARY KEY,
image_url VARCHAR(255) NOT NULL,
caption VARCHAR(255),
user_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(user_id) REFERENCES users(id)
);
CREATE TABLE comments (
id INT AUTO_INCREMENT PRIMARY KEY,
comment_text VARCHAR(255) NOT NULL,
user_id INT NOT NULL,
photo_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(user_id) REFERENCES users(id),
FOREIGN KEY(photo_id) REFERENCES photos(id)
);
CREATE TABLE likes (
user_id INT NOT NULL,
photo_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(user_id) REFERENCES users(id),
FOREIGN KEY(photo_id) REFERENCES photos(id),
PRIMARY KEY(user_id, photo_id)
);
CREATE TABLE follows (
follower_id INT NOT NULL,
followee_id INT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
FOREIGN KEY(follower_id) REFERENCES users(id),
FOREIGN KEY(followee_id) REFERENCES users(id),
PRIMARY KEY(follower_id, followee_id)
);
CREATE TABLE tags (
id INT AUTO_INCREMENT PRIMARY KEY,
tag_name VARCHAR(255) UNIQUE,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE photo_tags (
photo_id INT NOT NULL,
tag_id INT NOT NULL,
FOREIGN KEY(photo_id) REFERENCES photos(id),
FOREIGN KEY(tag_id) REFERENCES tags(id),
PRIMARY KEY(photo_id, tag_id)
);
reference