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

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

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

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

861閲覧

ぐちゃぐちゃなデータベースを正規化して作り直したい! でもどうやって…?

hacosato

総合スコア48

SQLite

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

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/11/23 14:08

先日の質問に関連しています。

SQLiteのファイルがあって、テーブルがふたつあります。
J-POPの曲をテーブルに収めてあります。

SQL

1CREATE TABLE oriconranking( 2 year int, 3 rank int, 4 title text, 5 artist text, 6 releasedate text 7 ); 8CREATE TABLE songs( 9 artist text, 10 title text, 11 lyricist text, 12 composer text, 13 releasedate text, 14 lyricURL text, 15 memo text, 16 lyric text);

テーブルoriconrankingには、年ごとにランクインした曲のタイトル、アーティストなどが入っています。
select * from oriconranking where title = '恋';
するとこういう感じです。

2017|24|恋|星野源|2016/10/05
2016|32|恋|星野源|2016/10/05
1980|34|恋|松山千春|1980/01/21

2017年に恋という曲が24位にランクインし、同一の曲が2016年に32位にランクインしていて、さらにちがう曲が1980年にもランクインしていることがわかります。

テーブルsongsには、たくさんの曲の情報が入っています。いまはオリコンにランクインしている曲しか入っていませんが、いずれオリコンには関係なく、いろんな曲の情報を入れたいです。
select * from songs where title = '恋するフォーチュンクッキー';
するとこういう感じです。

AKB48|恋するフォーチュンクッキー|秋元康|(略)|oricon2014|(略)
AKB48|恋するフォーチュンクッキー|秋元康|(略)|oricon2013|(略)

何年にランクインしているかがカラムmemoに「oricon0000」の感じで書いてあります。

テーブルsongsには、1曲につき1レコードにしたいのに、いま重複があるのでだめです…。
解消してきれいに作り直したいです。

作り直す方針としては、先日の質問でyonaさんに回答いただいたようにしたいです。
oriconranking2テーブルを以下のように作ろうと思っています。

oriconranking2テーブル
id:プライマリーキー
song_id:songsのプライマリーキー
year:ランクインした年(2017,2016等)

このように作り替えるにはどうしたらいいでしょうか?

わたしは、
0. テーブルsongsにカラムsongidを作って、rowidを当てる。
0. Pythonを使って、forループでテーブルsongsを1レコードずつなぞる。
0. カラムmemoを見て、それをテーブルoriconranking2に転記する。
0. カラムtitleとカラムartistを見て、いま注目しているレコードと重複していたらそのレコードを削除?

とかってやったらできるかな?と思うんですが、重複を解消する方法を考えていたら混乱してきました…。

SQLのほかにはPythonならすこし使えると思います。

お知恵を貸していただけたらうれしいです!

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

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

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

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

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

guest

回答1

0

ベストアンサー

重複を解消する方法を考えていたら混乱してきました

困っておられるようなので、
シンプルになるアイディアだけ言ってみてもいいですか。
(SQLは自力で考えてください)

ランキングと曲でテーブルを分けるのなら、
曲にランキング、ランキングに曲のデータは不要なのでは?

曲の方はJANコードを使えば重複を排除できます。
ランキングの方はそのJANコードだけ入れるとか。


ID年度順位JAN
120151123...
220152456...
320161789...
JAN曲名歌手
12345...恋しtail?LoveLoveWomen

上は単純化したサンプルです。
これがDB設計として良いかどうかともかく、
シンプルなのはシンプルだと思います。
少なくとも、質問の題の正規化はしてます。

なお、年度と順位の複合キーが自然ではありますが、
もし、オリコンのランキングが同率2位とかを許すなら、重複するので、
自動連番のIDを主キーにした方が確実かもしれません。


オリコンには関係なく、いろんな曲の情報を入れたいです

それならむしろ、JANコードが主で、ランキングの方を従、
と考えた方が、シンプルになりそうです。

アプリのドメインが、ランキングなのか、CD全体なのかの違いです。
かりに、本やゲームもDB化するなら、たとえば、AmazonのASINでもいいわけです。

投稿2017/11/23 16:24

編集2017/11/23 16:55
LLman

総合スコア5592

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

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

SVC34

2017/11/24 00:16

このあたりを考慮する必要がありそう - オリコンのランキングはJANコードが異なる限定版と通常版を区別していない - 廃盤になったCDのJANコードは使い回しされる可能性がある
miyabi-sun

2017/11/24 01:10

> 廃盤になったCDのJANコードは使い回しされる可能性がある 流通システム開発センターェ… そういやISBN(国際標準図書番号)も使いまわすゴミフォーマットじゃねーか!って誰かが憤慨してましたね。
LLman

2017/11/24 08:44 編集

あくまで、完全なDBの設計ではなく、 質問を整理するアイディアですからね……。 でも私も、JANやISBNの使い回しは、止めて欲しいと思います。 一意にするための規格番号の意味がなくなっちゃうでしょって思う。 代案としては、とくに広告売上を目的としたサイトの場合、ASINの方が明快かも。 かりに、ASINに重複があったとしても、 (というか、通常版と限定版を区別できてないとか、たまにありますが) 今度の場合そもそも、最終的に売上につなげるため、 ASIN以上に細かく分類する必要がない。 ただ、Amazon以外の楽天やヤフオクはどうするか、という問題は残ります。 理想としては、ASINみたいな独自規格の制定ですが、設計の負担が大きい。 小規模サービスなら割り切って自動連番、 またはASIN決め打ちでもいいと思います。 CDよりAmazonの方が長続きしそうなくらいだから。
hacosato

2017/11/24 14:25

ご回答ありがとうございます。 今回はCDになっていないような楽曲も含めたいため、 IDはわたしこのデータベース用に自動連番のIDを付与しようと思います。 JANやASINの話題で盛り上がっているところすみません…!! > ランキングと曲でテーブルを分けるのなら、 > 曲にランキング、ランキングに曲のデータは不要なのでは? じつは申し上げにくいのですが、当初からそういうふうにしようと思っていました…。 文面伝わりにくかったようでごめんなさい…! > それならむしろ、JANコードが主で、ランキングの方を従、 > と考えた方が、シンプルになりそうです。 こちらも、(JANではないですが)テーブルsongsのidを主として考えていました! いまは、このぐちゃぐちゃな感じのデータベースを前にして、 どういうアルゴリズムのプログラムを書いたらきれいなデータベースに整理し直せるのかについて、 アイディアをいただけたら助かるなと考えています。 わたしの誤認がありましたらお知らせください…。 引き続きよろしくお願いします!
LLman

2017/11/24 15:04 編集

>どういうアルゴリズムのプログラムを書いたら >きれいなデータベースに整理し直せるのか あー、「旧DBから新DBへ、データを移行したい」って意味でしたか? DBのデータ取得がスクレイピングなど自動的なものなら、 今のデータは全部捨てちゃっても問題ないでしょうが、 手作業で大量に入力したりして、捨てたくない場合もあるでしょう。 その場合の、データを移行するプログラムのアルゴリズムですが、 前提として、外部に公開するものではない、一度きりの書き捨てですから、 パフォーマンスとか気にしない、泥くさい愚直なものでいいわけです。 そこで、一番単純な方法としては、結果から逆算して、【新DBを基準】にします。 たとえば、2015年1月の1位、2位、3位……と並んでいるなら、 それを旧DBから検索して順番に取ってくるプログラムを書きます。 こうすると、並べるだけで、重複がどうとか考える必要がなくなります。 処理がすごい遅くなると思いますが、別に何時間かかってもいいでしょう。 逆に、「最小手順で移行するアルゴリズム」とか考える方が時間が掛かります。
hacosato

2017/11/25 01:33

あーそっか、わかりました! ありがとうございます。 いままで、既存のテーブルsongsを順番にさらいながら、 必要ない部分を書き換えたり取り除いたりする方法を考えてたんですが、 テーブルsongsはそのままほっといて、新しいテーブルを作っていけばいいんですね。 で、最後にいらなくなったテーブルsongsを消せばいいんだ…天才……! スクレイピングした部分もたくさんあるんですが、結局手作業で名寄せしたりしてたので、 データを失うのはつらかったんです。でもこれなら大丈夫! ちょっとすぐに時間をつくれないんですが、あとでやってみます。 お付き合いいただいてありがとうございます〜。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問