#10 Nomalization
#10.1 Normalizing Status
-- status ๋นผ๊ธฐ
CREATE TABLE statuses (
status_id BIGINT UNSIGNED PRIMARY KEY auto_increment,
status_name ENUM (
'Canceled',
'In Production',
'Planned',
'Post Production',
'Released',
'Rumored'
) NOT NULL,
explanation TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
)
INSERT INTO statuses (status_name) SELECT status from movies GROUP BY status;
-- value ๋์ select ๋ฌธ ์ฌ์ฉ ๊ฐ๋ฅ
-- status_id ์์ฑ ํ ์ฐ๊ฒฐ
ALTER TABLE movies ADD COLUMN status_id BIGINT UNSIGNED;
ALTER TABLE movies ADD CONSTRAINT fk_status FOREIGN KEY (status_id) REFERENCES statuses (status_id) ON DELETE SET NULL;
-- ๊ธฐ์กด ๋ฐ์ดํฐ ๊ธฐ์ค์ผ๋ก id ๊ฐ ์ ์ฉ
UPDATE movies SET status_id = (SELECT status_id FROM statuses WHERE status_name = movies.status);
-- ๊ธฐ์กด status ์ ๊ฑฐ
ALTER TABLE movies DROP COLUMN status;
#10.2 Normalizing Directors
-- director ํ
์ด๋ธ ์์ฑ
CREATE TABLE directors (
director_id BIGINT UNSIGNED PRIMARY KEY auto_increment,
name varchar(120),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
);
-- uniqueํ๊ฐ๋
๋ช
์ถ๊ฐ
INSERT INTO
directors (name)
SELECT director
FROM movies
GROUP BY director
HAVING director <> '';
-- director_id ์์ฑ ํ ์ฐ๊ฒฐ
ALTER TABLE movies ADD COLUMN director_id BIGINT UNSIGNED;
ALTER TABLE movies ADD CONSTRAINT fk_director FOREIGN KEY (director_id) REFERENCES directors (director_id) ON DELETE SET NULL;
-- index, ๋น ๋ฅธ ์คํ์ ์ํ ์์
. ํ
์ด๋ธ ์์ฑ์ unique ์์
์ ํ๋ฉด ์ํด๋ ๋จ
CREATE INDEX idx_director_name ON directors (name);
UPDATE movies SET director_id = (SELECT director_id FROM directors WHERE name = movies.director);
-- ๊ธฐ์กด director ์ ๊ฑฐ
ALTER TABLE movies DROP COLUMN director;
#10.3 Normalizing Original Language
CREATE TABLE langs (
lang_id BIGINT UNSIGNED PRIMARY KEY auto_increment,
name varchar(120),
code char(2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
);
INSERT INTO
langs (code)
SELECT original_language
FROM movies
GROUP BY original_language;
ALTER TABLE movies ADD COLUMN original_lang_id BIGINT UNSIGNED;
ALTER TABLE movies ADD CONSTRAINT fk_org_lang FOREIGN KEY (original_lang_id) REFERENCES langs (lang_id) ON DELETE SET NULL;
UPDATE movies SET original_lang_id = (SELECT lang_id FROM langs WHERE code = movies.original_language);
-- ๊ธฐ์กด original_language ์ ๊ฑฐ
ALTER TABLE movies DROP COLUMN original_language;
#10.4 Normalizing Countries
CREATE TABLE countries (
country_id BIGINT UNSIGNED PRIMARY KEY auto_increment,
country_code char(2) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL
);
INSERT INTO countries (country_code)
SELECT country
FROM movies
WHERE country NOT LIKE '%,%'
GROUP BY country;
SELECT country, SUBSTRING_INDEX(country, ',', 1),SUBSTRING_INDEX(country, ',', -1)
FROM movies
WHERE country LIKE '__,__'
GROUP BY country;
#10.5 Unions
-- join ----
/*
union
-
-
-
-
*/
INSERT IGNORE INTO countries (country_code)
SELECT SUBSTRING_INDEX(country, ',', 1)
FROM movies
WHERE country LIKE '__,__'
GROUP BY country
UNION
SELECT SUBSTRING_INDEX(country, ',', -1)
FROM movies
WHERE country LIKE '__,__'
GROUP BY country;
#10.6 Conclusions
INSERT IGNORE INTO countries (country_code)
SELECT SUBSTRING_INDEX(country, ',', 1)
FROM movies
WHERE country LIKE '__,__,__'
GROUP BY country
UNION
SELECT SUBSTRING_INDEX(country, ',', -1)
FROM movies
WHERE country LIKE '__,__,__'
GROUP BY country
UNION
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(country, ',', 2), ',', -1)
FROM movies
WHERE country LIKE '__,__,__'
GROUP BY country;
CREATE TABLE movies_countries (
movie_id BIGINT unsigned,
country_id BIGINT unsigned,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (movie_id, country_id),
FOREIGN KEY (movie_id) REFERENCES movies (movie_id) ON DELETE CASCADE,
FOREIGN KEY (country_id) REFERENCES countries (country_id) ON DELETE CASCADE
);
INSERT INTO movies_countries (movie_id, country_id)
SELECT movies.movie_id, countries.country_id
FROM movies JOIN countries ON movies.country LIKE CONCAT('%', countries.country_code, '%')
WHERE movies.country <> '' AND countries.country_code <> '';
ALTER TABLE movies DROP COLUMN country;
ALTER TABLE movies DROP COLUMN country;
Last updated
Was this helpful?