View on GitHub

ユーザ、アイテム、評価値テーブルの設計とデータの登録

Home

ユーザ、アイテム、評価値テーブルの設計とデータの登録

推薦システムで利用する各テーブルを設計しましょう。まず、基本的なデータとして、ユーザ、アイテム、評価値に関するテーブルを設計します。それぞれ、次のようなテーブルを設計することにします。

users

カラム名説明データ型制約
user_idユーザIDINTPRIMARY KEY
nameユーザ名TEXTNOT NULL
age年齢INT
sex性別CHAR(1)

items

カラム名説明データ型制約
item_idアイテムIDINTPRIMARY KEY
nameアイテム名TEXTNOT NULL
red赤身INT
white白身INT
shining光物INT

ratings

カラム名説明データ型制約
idIDSERIALPRIMARY KEY
user_idユーザIDINTFOREIGN KEY(users.user_id), NOT NULL
item_idアイテムIDINTFOREIGN KEY(items.item_id), NOT NULL
rating評価値INTNOT NULL

ここで、ratingsテーブルではidを主キーとしています。(user_id, item_id)の複合キーを主キーとしても良いのですが、Djangoのモデルで複合キーを扱おうとすると複雑になりますので、ここでは別途idを用意し、これを主キーとすることにします。また、idのデータ型をSERIALとしています。これは、データ登録時にidを省略したとき、idには自動的に連番が振られることを表しています。

以上のテーブルをPostgreSQLのrecsys_djangoデータベース上で作成します。PostgreSQL上で下記のコマンドを実行してください。

recsys_django=#
CREATE TABLE users(
    user_id INT,
    name TEXT NOT NULL,
    age INT,
    sex CHAR(1),
    PRIMARY KEY(user_id)
);

recsys_django=#
CREATE TABLE items(
    item_id INT,
    name TEXT NOT NULL,
    red INT,
    white INT,
    shining INT,
    PRIMARY KEY(item_id)
);

recsys_django=#
CREATE TABLE ratings(
    id SERIAL,
    user_id INT NOT NULL,
    item_id INT NOT NULL,
    rating INT NOT NULL,
    PRIMARY KEY(id),
    FOREIGN KEY(user_id) REFERENCES users(user_id),
    FOREIGN KEY(item_id) REFERENCES items(item_id)
);

下記のコマンドで、作成されたテーブルを確認してみましょう。

recsys_django=# \dt
                        List of relations
 Schema |                 Name                 | Type  |  Owner   
--------+--------------------------------------+-------+----------
...(略)...
 public | items                                | table | postgres
 public | ratings                              | table | postgres
 public | users                                | table | postgres
(13 rows)

usersitemsratingsの三つのテーブルが作成されていることが確認できました。ただし、テーブルの所有者Ownerpostgresとなっているので、recsys_djangoプロジェクトからアクセスできるように、これをrslに変更しておきましょう。それぞれ、下記のコマンドを実行して各テーブルの所有者を変更してください。

recsys_django=# ALTER TABLE users OWNER TO rsl;
ALTER TABLE
recsys_django=# ALTER TABLE items OWNER TO rsl;
ALTER TABLE
recsys_django=# ALTER TABLE ratings OWNER TO rsl;
ALTER TABLE

下記のように、Ownerrslに変更されました。

recsys_django=# \dt
                        List of relations
 Schema |                 Name                 | Type  |  Owner   
--------+--------------------------------------+-------+----------
...(略)...
 public | items                                | table | rsl
 public | ratings                              | table | rsl
 public | users                                | table | rsl
(13 rows)

作成したテーブルの構造は下記のコマンドで表示することができます。

recsys_django=# \d users
                  Table "public.users"
 Column  |     Type     | Collation | Nullable | Default 
---------+--------------+-----------+----------+---------
 user_id | integer      |           | not null | 
 name    | text         |           | not null | 
 age     | integer      |           |          | 
 sex     | character(1) |           |          | 
Indexes:
    "users_pkey" PRIMARY KEY, btree (user_id)
Referenced by:
    TABLE "ratings" CONSTRAINT "ratings_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(user_id)

設計したとおりのテーブル構造になっていることが確認できます。itemsテーブル、ratingsテーブルについても確認しておきましょう。

さて、現時点では、それぞれテーブルの枠組みを用意しただけで、データはまだ登録されていません。それぞれ、ユーザ、アイテム、評価値に関するデータを登録していきましょう。本チュートリアルでは、サンプルデータをrecsyslab/recsys-django/contents/recsys_django/offline/data/に置いています。この中のusers.csvitems.csvratings.csvを任意のディレクトリにダウンロードしてください。そして、PostgreSQL上でそれぞれ下記のコマンドを実行してください。ここで、【ディレクトリ】には各ファイルを置いているディレクトリを入力してください。

recsys_django=# COPY users FROM '【ディレクトリ】/users.csv' (DELIMITER E'\t', FORMAT csv, HEADER TRUE, ENCODING 'UTF-8');
COPY 5
recsys_django=# COPY items FROM '【ディレクトリ】/items.csv' (DELIMITER E'\t', FORMAT csv, HEADER TRUE, ENCODING 'UTF-8');
COPY 9
recsys_django=# COPY ratings FROM '【ディレクトリ】/ratings.csv' (DELIMITER E'\t', FORMAT csv, HEADER TRUE, ENCODING 'UTF-8');
COPY 28
recsys_django=# SELECT setval('ratings_id_seq', (SELECT max(id) FROM ratings));
 setval 
--------
     28
(1 row)

ここで、最後のコマンドでidのシーケンス値を更新しています。今回はratings.csvからid=28までを強制的に登録しましたので、シーケンス値を28に設定することで、次回データが登録されるときにその次の値である29が自動的に振られるようにしています。

これで、各テーブルへのデータの登録ができました。usersテーブルの内容を確認してみましょう。

recsys_django=# SELECT * FROM users;
 user_id |  name  | age | sex 
---------+--------+-----+-----
       1 | Alice  |  20 | f
       2 | Bruno  |  22 | m
       3 | Chiara |  21 | f
       4 | Dhruv  |  21 | m
       5 | Emi    |  20 | f
(5 rows)

itemsテーブル、ratingsテーブルについても内容を確認しておきましょう。