我正在尝试为movielens(http://grouplens.org/datasets/movielens/)创建一个数据库。我们有电影和收视率。电影有多种类型。我把它们拆分成一个单独的表,因为这是一个很多的关系。有很多:很多关系,用户也喜欢电影。我需要能够以多种方式查询此表。
所以我创建了:
CREATE TABLE genre (
genre_id serial NOT NULL,
genre_name char(20) DEFAULT NULL,
PRIMARY KEY (genre_id)
)
INSERT INTO genre VALUES
(1,'Action'),(2,'Adventure'),(3,'Animation'),(4,'Children\s'),(5,'Comedy'),(6,'Crime'),
(7,'Documentary'),(8,'Drama'),(9,'Fantasy'),(10,'Film-Noir'),(11,'Horror'),(12,'Musical'),
(13,'Mystery'),(14,'Romance'),(15,'Sci-Fi'),(16,'Thriller'),(17,'War'),(18,'Western');
CREATE TABLE movie (
movie_id int NOT NULL DEFAULT '0',
movie_name char(75) DEFAULT NULL,
movie_year smallint DEFAULT NULL,
PRIMARY KEY (movie_id)
);
CREATE TABLE moviegenre (
movie_id int NOT NULL DEFAULT '0',
genre_id tinyint NOT NULL DEFAULT '0',
PRIMARY KEY (movie_id, genre_id)
);
我不知道如何导入带有 movie_id,movie_name和movie_genre 列的movies.csv例如,第一行是(1;Toy Story (1995);Animation|Children's|Comedy)
如果我手动插入,它应该如下所示:
INSERT INTO moviegenre VALUES (1,3),(1,4),(1,5)
因为3是动画,4是儿童,5是喜剧
如何以这种方式导入所有数据?
答案 0 :(得分:1)
您应首先创建一个可以从CSV文件中提取数据的表:
CREATE TABLE movies_csv (
movie_id integer,
movie_name varchar,
movie_genre varchar
);
请注意,任何单引号(Children's
)都应加倍(Children''s
)。一旦数据进入此临时表,您就可以将数据复制到movie
表,该表应具有以下结构:
CREATE TABLE movie (
movie_id integer, -- A primary key has implicit NOT NULL and should not have default
movie_name varchar NOT NULL, -- Movie should have a name, varchar more flexible
movie_year integer, -- Regular integer is more efficient
PRIMARY KEY (movie_id)
);
同样消毒你的其他桌子。
现在复制数据,从CSV名称中提取未加修饰的名称和年份:
INSERT INTO movie (movie_id, movie_name)
SELECT parts[1], parts[2]::integer
FROM movies_csv, regexp_matches(movie_name, '([[:ascii:]]*)\s\(([\d]*)\)$') p(parts)
([[:ascii:]]*)
- 捕获所有字符,直到下面的匹配\s
- 阅读空格\(
- 阅读一个左括号([\d]*)
- 捕获任何数字\)
- 阅读右括号$
- 从字符串末尾开始匹配所以在输入"死硬17(约翰永远活着)(2074)"它创建一个带{'Die Hard 17 (John lives forever)', '2074'}
的字符串数组。假设所有电影标题以括号中的出版年份结束,扫描必须来自结尾$
,以保留电影标题中的括号和数字。
现在你可以处理电影类型了。您必须使用|
函数拆分条regex_split_to_table()
上的字符串,然后加入到类型名称的genre
表中:
INSERT INTO moviegenre
SELECT movie_id, genre_id
FROM movies_csv, regexp_split_to_table(movie_genre, '\|') p(genre) -- escape the |
JOIN genre ON genre.genre_name = p.genre;
完成所有操作后,您可以删除movies_csv
表。