質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

解決済

4回答

2412閲覧

ちょっと種類が違うけど結構似てるレコード。ひとつのテーブルに混ぜてもOK?

hacosato

総合スコア48

SQLite

SQLiteはリレーショナルデータベース管理システムの1つで、サーバーではなくライブラリとして使用されている。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

0グッド

0クリップ

投稿2019/01/12 16:21

編集2019/01/13 01:20

勉強のために、SQLiteで音楽のデータベースを作っています。ふわっとしたお話なのですが…。

songsというテーブルがあり、title、artist、type(楽曲の種類・後述)、length(曲の長さ)、releasedDate(リリース日)、URLといったカラムがあります。
ほかにもいろいろありますがここでは省略します。

そのテーブルに、
type=1:CDの発売をもってリリースとされる楽曲(たとえばAKB48『365日の紙飛行機』)と、
type=2:動画公開をもってリリースとされる、それ以外の楽曲(たとえば黒うさP feat.初音ミク『千本桜』)を
両方入れようと思っています。

type=2のような曲にはURLが存在するので記入します。type=1のような曲には記入しません。

releasedDateには、type=1の場合CDの発売日、type=2の場合動画の公開日などが入ります。

type=1とtype=2を比べて、length(曲の長さ)に違いがあるかなどをのちのち調べるためにデータを作ります。

…といった状況のときに、type=1とtype=2のデータを同じテーブルに入れるのはアリでしょうか?

わたしはべつにいいかなと思っていたんですが、

https://employment.en-japan.com/engineerhub/entry/2018/12/11/110000

ここに、リファクタリングすべきデータベースの例として、

複数の目的に使われるカラム
レコードの属性に合わせて値の意味が変わるカラム
会員だと入会日、スタッフだと入社日とするなど

とあったので、自分の方針はよくないかなぁとも思い相談しました。

この場合、テーブルを分けるのがいいような気もしますが、

「あっやっぱり楽曲ごとに作曲者の情報も載せることにしよう! composerカラムを作るぞ!」

と(あまりよくないですが)なった場合、ふたつのテーブルに対して同じカラムを増やしたものを用意したりするのはよい方法とはいえない気もします。

最終的には自分がどうしたいか?みたいなところに行き着く感じもするのですが、このような状況で、データベース強者はどのような基準で判断して設計していくのかについて、お話を聞かせていただけたらと思います!

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

DBの寿命はアプリより長い! 長生きするDBに必要な設計とリファクタリングを実践から学ぶ

ご自身で示されている上記リンク先にも書かれていますが、releasedDateデータ情報の何れだと思われますか?

releasedDateには、type=1の場合CDの発売日、type=2の場合動画の公開日などが入ります。

追記

例えば、楽曲に対してCDや動画をメディアとして別なテーブルとして括ると、typereleasedDateを行として管理していても問題はありません。
行として管理するか、列として管理するかというのは、扱うDBMSによって効率の良いアクセスになるかだとかリソースの問題(無駄なカラム)なども絡んできます。

データの持ち方として重要なのは、情報をロストしないこと。
そのためには格納出来ないなどとならない構造である事です。

投稿2019/01/13 00:56

編集2019/01/13 03:48
sazi

総合スコア25138

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sazi

2019/01/13 01:06 編集

情報は効率を考えて必要なら付加するというように考えると良いですね。
hacosato

2019/01/13 01:46

ありがとうございます。 releasedDateはデータだと思いました! リンク先の例に挙がっている生年月日と同じようなものだから! …と思っていたんですが間違いでしょうか? せっかく示唆いただいたので考えてみたのですが、よくわかりませんでした……。
sazi

2019/01/13 02:03 編集

発売日や公開日を読み替えているので編集ですね。 読み替えている行為があなたによって登録時に行われているので、データだと思うのでしょう。 typeの判断で発売日や公開日に読み替えできると思うかもしれませんが、同じ楽曲に対して動画もCDある場合、何れかしか格納できないので、レイアウトを変更しないなら、type+楽曲コードをキーにするしかなくなります。
hacosato

2019/01/13 02:08

ありがとうございます! id:Kaiserさんにもアドバイスいただいた通り、かりにテーブルひとつでまかなうなら、 releasedDateのほかにsubscriptionDateというカラムを作らないといけないですね。 そうするとtypeカラムも必要なくなる…。
guest

0

ベストアンサー

判断が難しい事柄です。私もさんざん迷いました。

私の考え方を共有します。

マスタ系は、可能な限り正規化すべきです。
トランザクション系は、ある程度許容するが、スーパータイプとサブタイプは分けるべき。

つまり、今回の質問で言うと、マスタ系にあたるので
分けたほうが良いと思います。

私でしたら、このようなマスタにします。
ちなみに、私の提示した楽曲マスタに良くない部分があります。
作詞者と作曲者列があまりよくないです。

■楽曲マスタ

楽曲コード楽曲名作詞者作曲者CDリリース動画配信
0001千本桜 feat.初音ミク黒うさP黒うさP

■動画配信マスタ

楽曲コード配信日URL
00012018/04/29https://teratail.com/questions/168505

■CDマスタ

楽曲コードリリース日
00012018/04/29

考え方としては、動画配信とCDリリースで共通する部分は
楽曲マスタに入っています。
楽曲マスタには、CDリリース、動画配信があるのか表現しています。
動画配信マスタとCDマスタにはそれぞれ、個別の列を定義しています。

メリット
・動画配信、CDリリースの両方に対応する楽曲に対応できる。
・共通項目の変更追加があった時は、楽曲マスタを修正すればよいです。
・各マスタに無駄な列「NULL」ができない
・各マスタの列が最小限になるので見渡しがよくなる

CDリリース、動画配信列は、動画配信マスタにあるかないかで判断できるので
無駄な気もするのですが、楽曲マスタだけですべての情報を見渡せるので、個人的にはこちらが好きです。

デメリット
・テーブルの数が増えるので、JOINが必要になる。
→VIEWで回避可能。
・テーブルの数が増えるので、管理が大変になる
・JOINするのでパフォーマンスに影響がある
→マスタ系だったら、そこまで影響は無いと思うのですが。
リスクはあるということで。

releasedDateに異なる意味の値を入れるのは避けた方が良いと思います。
多少無駄になっても、subscriptionDateとかにしたほうが良いかと思います。
後で誰かが見たときに誤解が生じます。
脳内でtype1だったらこういう意味。と変換する必要も生じます。

もう一つ分ける理由を説明すると、
最初はわずかな違いなので、一つにまとめたテーブルでも
結局後から、どんどん違いが出てきて分けたほうが良かった。ということが結構あります。

なので、基本は分ける。
その後、違いが小さいことが確定したり、パフォーマンスに影響出るようであれば
適宜まとめていく。という考え方がよろしいかと思います。

投稿2019/01/12 22:27

Kaiser

総合スコア295

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hacosato

2019/01/13 01:34

ありがとうございます! > 作詞者と作曲者列があまりよくないです。 この2つを外部キーとして、さらに新しいテーブルをつくってそこに黒うさPを格納する、 というのがさらによい方法ということで合ってますか?? > CDリリース、動画配信列は、動画配信マスタにあるかないかで判断できるので > 無駄な気もするのですが、楽曲マスタだけですべての情報を見渡せるので、個人的にはこちらが好きです。 わたしも上から順に読んでいったとき、楽曲マスタのテーブルのこの2つのカラムには疑問がありました。 このふたつはなくしても情報量が損なわれるわけではないですよね? また、最初はtype=2だと思っていた(動画配信だけだと思っていた)のに、あとからCDがリリースされた!という場合、 動画配信マスタのテーブルに1つレコードを追加する必要があるのと同時に、 楽曲マスタのテーブルの当該楽曲レコードのCDリリースカラムを修正しなければならず、 もしどちらか片方の修正を忘れてしまった場合にデータが壊れてしまうと理解しています。 しかし「楽曲マスタだけですべての情報を見渡せる」のはたいへんステキなメリットなので、 それを天秤にかけてどちらがよいか選択しましょう、ということかと思っています。 よく本やWebに、正規化が不十分でも運用上の都合を優先することもある、 と書いてあるのはこのことでしょうか?
Kaiser

2019/01/13 22:27

>この2つを外部キーとして、さらに新しいテーブルをつくってそこに黒うさPを格納する、 >というのがさらによい方法ということで合ってますか??  はい。そうです。作曲者マスタみたいなものがあるのがベターです。 >よく本やWebに、正規化が不十分でも運用上の都合を優先することもある、 >と書いてあるのはこのことでしょうか?  はい。そうです。ただ、データが壊れる可能性があるなら、カラムは消してしまった方が良いと思ってきました。  いずれにせよ、まずは正規化ありきで考えて、運用の都合やパフォーマンスを見て  ベストなテーブル定義を求めていくのが、スマートなやり方だと思っています。
hacosato

2019/01/14 02:54

さらなるお返事ありがとうございました。とてもよくわかりました! id:mts10806さんとの会話にも出てきましたが、 作曲者マスタがあると、同名の人物を区別できるようになりますね。 やっぱり正規化を優先で考えて、CDリリースと動画配信のカラムはなしでやってみます。 JOINは苦手だけどがんばろう…!
guest

0

「結構似てる」はもはや別のものでは。

投稿2019/01/13 01:23

m.ts10806

総合スコア80765

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hacosato

2019/01/13 01:47

やっぱりそうですかね…テーブル分けるかな…。
m.ts10806

2019/01/13 09:04

極端な例、同姓同名だけど性別が違うとかそういうのと同じかと。
hacosato

2019/01/13 11:06

さっき設計を考えててその可能性に思い当たり震えあがりました…最初はテーブル1コでいいじゃんと思っていたんですけどどんどん壮大になりますね……。
guest

0

テーブルをひとつにまとめるか、複数に分けるかは判断が難しい場合が多いです。どんなSQLが必要か考えてみると良いでしょう。

たとえばSELECTでUNIONまたはUNION ALLを多用しないといけないなら、パフォーマンスが悪いのでひとつのテーブルにまとめるべきだ、って判断します。

投稿2019/01/12 17:50

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hacosato

2019/01/13 01:22

ありがとうございます。たしかにUNIONをそれなりに使うことになる気がします。 この頻度がどれぐらいなのかによって判断するのは、基準としてわかりやすいです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問