bash - 音乐图表跟踪器的SQLite数据库设计

标签 bash database-design sqlite relational-database

我一直在整理一个小的SQLite数据库,以跟踪iTunes RSS feed中的前100首歌曲。我已经在Bash中构建了脚本来完成所有艰苦的工作,并且终于工作了,但是我不确定我的数据库结构是否正确,所以我正在寻找有关最佳方法的反馈,因为我只是目前正在学习SQL,因此在构建查询以及时检索数据时,我不想陷入困境!

我有3张桌子。

artist_table

artist_id - PK
artist_name


songs_table

song_id - PK
artist_id - FK (from the artists table)


chart_table

chart_id - PK
song_id - FK (from the songs table)
position - (chart position 1-100)
date - (date of chart position xxxx-xx-xx)


Artists和Songs表对我来说似乎很好,可以使用外键约束...等等,但是我不确定Charts表,这种结构显然有什么问题吗?

我想跟踪一段时间内的歌曲/艺术​​家/位置,以便生成一些统计信息...等等

谢谢,

最佳答案

初步反应

我询问您有关数据的信息,以便回答您的​​问题,但是您一直在告诉我有关过程的信息。毫无疑问,这对您非常重要。现在,您希望确保记录归档系统正确。

就个人而言,在设计数据库之前,我永远不会编写任何代码。部分原因是我讨厌重写代码(而且我喜欢编写代码)。您的顺序颠倒了,这些天来是不幸的趋势。这意味着,无论我给您什么,您都将不得不重写大量代码。


(b.1)如何精确检查歌手(歌曲)是否已经存在?

(b.2)您如何知道存档的特定艺术家/歌曲的occ不超过?


现在,考虑到您的问题中的详细信息,比方说您已经收到,Pussycat Dolls今天在MTV图表上排名66:

    INSERT artist VALUES ( "Pussycat Dolls" )    -- succeeds, intended
    INSERT artist VALUES ( "Pussycat Dolls" )    -- succeeds, unintended
    INSERT artist VALUES ( "Pussycat Dolls" )    -- succeeds, unintended



究竟哪个Pussycat Dolls记录今天排名第66位?
当您的RFS增长时,您在artist中会有更多字段,例如。 birth_date,您要更新三个记录中的哪个?
与歌曲同上。
如何识别图表,是否类似于US Top 40



(b.1)如何精确检查歌手(歌曲)是否已经存在?


当您执行代码时,它将在sqLite程序中运行。您传递的确切SQL字符串是什么?假设您这样做:

    SELECT $artist_id = artist_id
            FROM artist
            WHERE artist_name = $artist_name
    IF $artist_id = NULL
        INSERT artist VALUES ( $artist_name )


然后,当系统“上线”时,您将有一些惊喜。希望这种互动将消除它们。现在您有几百个艺术家。


当您有几千个艺术家时,该系统的运行速度将减慢。
出现问题时,您将拥有重复的歌手,歌曲和图表。


记录备案系统

现在,您拥有1970年前的ISAM记录归档系统,没有关系完整性,功能或速度。

如果您想进一步了解RFS的危险,请在当今的关系上下文中阅读this Answer

关系型数据库

据我了解,您需要关系数据库的完整性,功能和速度。这就是您要去的方向。显然,它是不完整的,未经证实的,可能缺少细节,许多问题仍未解决。但是我们必须对数据进行建模,仅将其建模为数据(与您将要处理的数据,流程相对),而仅对数据建模。

这种方法将确保很多事情:


随着数据的增长和添加(根据结构而不是数量),现有数据和代码将不会更改
您将拥有数据和参照完整性
您可以通过一个SELECT命令获得每个统计信息。
您可以针对数据执行任何SELECT,甚至您梦of以求的SELECT也可以执行,这意味着无限的统计信息。只要数据以关系形式存储。


数据库是有关现实世界的事实的集合,仅限于关注的主题领域。到目前为止,我们还没有事实,我们记录了传入的RSS流。而且录音没有完整性,您的代码没有任何依赖。这是朝着事实的方向前进:

音乐图表初稿TRD(由于进度过时,请参见下文。)

对评论1的回应


目前,我只跟踪一个图表,但是在您的模型中我看到它也具有跟踪多个图表的功能,这很好!


并不是的。这是“正确做事”的副作用。这里的问题是身份证明之一。图表位置不能由RSS Feed IDchart_table.id,PositionNoDateTime.编号来标识。图表位置被标识为US Top 100/27 Apr 15/1…副作用是ChartName是标识符的一部分,并且允许多个图表,而无需其他编码。

在IT的黑暗日子里,人们经常为一个国家/地区编写系统,并在各处实施StateCode。当他们向国际客户群开放时,便会遇到巨大的问题。关键是,没有一个国家没有一个国家,一个国家仅在一个国家的背景下存在。因此,州识别码必须包含国家/地区识别码,它是(CountryCode, StateCode).澳大利亚和加拿大的NT均具有StateCode.


如果可以解释如何存储rss feed中的数据,则可能会有所帮助。


不谢谢。这与数据有关,仅与数据有关。请查看我以前对该问题的评论及其好处。


目前我不在主机上,但是如果可以的话,我会在接下来的几个小时内做出回应。


别担心。我明天去。


你的模特对我来说确实有意义,


那是因为您非常了解数据值,但您却不了解数据,并且当有人正确地为您布置数据时,您会遇到愉悦的小小的抽搐。


我不介意重新编码所有内容,这是学习曲线!


这是因为您将购物车放到了前面,并根据电子表格中的数据进行了编码,而不是先设计数据库,然后再对数据库进行编码。

如果您不习惯该符号,请注意,实线与虚线,方格与圆角之间的每一个小滴答,刻痕和记号,都意味着非常具体。请参考IDEF1X Notation

对评论2的回应


只是一个快速的问题。


开除,直到您完全满意为止。


在该图中,将歌手表放在歌曲表上方并将歌曲表改为父歌手的孩子会有任何不利之处吗?由于艺术家可以有很多歌曲,但是每首歌曲只能有1位艺术家。是否有必要使附加表仅包含artistPK和songPK。我不能将artistPK作为FK存储到歌曲表中,因为只有存在关联的歌手时,歌曲才能存在吗?



注意您对组织方式的依恋。我重复:




数据库是有关现实世界的事实的集合,仅限于关注的主题领域。



事实是合乎逻辑的,而不是物理上的。当这些事实被正确组织(规范化,设计化)时:



您可以对数据执行任何SELECT,甚至可以执行您梦dream以求的SELECT,这意味着无限的统计信息。只要数据以关系形式存储。



如果不是,那你就不能。针对数据的所有SQL(不仅是预想的报告)都限于模型中的限制,归结为一件事:离散事实是否以逻辑形式记录。

借助TRD,我们已开始记录有关真实世界的事实,仅受应用程序范围的限制,而不受事实的不分散性限制。


我不能将artistPK作为FK存储到歌曲表中,因为只有存在关联的歌手时,歌曲才能存在吗?


在您的工作环境中,这是事实。但这在您录制的现实世界中是不正确的。如果应用程序或您的范围发生了变化,则您将不得不更改数据库和应用程序的详细信息。如果您正确记录事实(存在的事实),而不是仅限于当前应用程序范围,则当应用程序或您的范围更改时,无需进行此类更改(请确保您必须添加对象和代码,而无需修改现有的对象和代码)。

在现实世界中,SongArtist是离散的事实,彼此可以独立存在。您的主张是错误的。


在凯伦·卡彭特(Karen Carpenter)记录下来之前,圣母玛利亚(Ave Maria)存在了16个世纪。
并且您已经理解并接受Artist存在而没有`Song。



是否有必要使附加表仅包含artistPK和songPK。


它不是“仅包含artistPK和songPK的附加表”,它记录的是离散事实(与ArtistSong的独立存在分离),特定的Artist记录了特定的 ChartDatePosition`

您的主张将Song. That is the fact that you will count on in the依赖于Song,从属于Artist,但这根本不是事实。任何基于Song的统计信息(无论是否梦想)都必须导航Artist::ArtistSong,然后进行排序或ORDER BY,等。


艺术家可以有很多歌曲,但是每首歌曲只能有1位艺术家。


这是半正确的(在您当前的工作环境中是正确的,但在现实世界中则不是)。事实是:


Each Artist is independent
Each Song is independent
Each Artist recorded 1-to-n Songs (via ArtistSong)
Each Song was recorded by 1-to-n Artists (via ArtistSong)


为了理解,在上面更改您的词以形成正确的命题(与陈述技术上正确的谓词相反):


Artists can have many RecordedSongs
Each RecordedSong can only have 1 Artist
Each RecordedSong can only have 1 Song


是的,有缺点,也有很大的缺点。

这就是为什么我声明,您必须将自己与应用程序,使用情况分开,并将数据建模为数据,除了数据之外,什么也没有。

解决方案2

我已经更新了TRD。

第二稿Music Chart TRD


Courier表示示例数据;蓝色表示密钥(始终是第一密钥);管道表示柱分离;斜杠表示备用键(仅显示不在PK中的列);绿色表示非关键。
我现在给您这些谓词。由于许多原因,这些非常重要。这里的主要原因是,它消除了我们正在讨论的问题的歧义。


如果您想了解有关谓词的更多信息,请访问this Answer,向下滚动(向下!)到谓词,然后阅读该部分。还要评估该TRD以及那些针对它的谓词。

ChartDateSong上的索引需要说明。起初,我假设:

   PK ( Chart, Date, Rank )


但是出于完整性目的以及搜索的需要,我们需要:

   AK ( Chart, Date, ArtistId, SongId )


PK更好。所以我换了。我们确实需要两者。 (我不了解NONsqLite,如果它具有聚簇索引,则AK,而不是PK应该聚簇。)

   PK ( Chart, Date, ArtistId, SongId ) 
   AK ( Chart, Date, Rank )



对评论3的回应


当某首歌曲进入图表时,其歌曲名称与song_table中的记录相同,但完全不相关(不是翻唱,完全是原始的,只是碰巧使用相同的名称),该场景怎么办?


在被称为欺诈的文明国家中,通过欺骗获得利益,但我会尝试以恶魔般的眼光思考一下,并回答这个问题。

好吧,如果发生的话,那么您必须迎合它。提要如何通知您此类事件?我相信不是。因此,您的歌曲标识符仍然是名称。


而不是创建唯一的歌曲记录,而是将现有的song_id与艺术家ID添加到artistsongs_table中,这不是问题吗?


我们没有更好的了解,所以这不是问题。没有人看着提要更好。如果并且当您通过任何渠道收到通知您该问题的数据,并且可以指定它,则可以对其进行更改。

通常,我们有一个应用程序,可让我们浏览层次结构并进行更改,例如。 ReferenceMaintenance应用程序,左侧为Exporer类型的窗口,右侧为组合对话框(顶部是occs列表,底部是一个occ的详细信息)。

在此之前,它不是一种损坏形式,因为防止这种损坏的约束条件尚未定义。您不会因违反尚未制定的法律而感到内gui。除非处于流氓状态。


尽管一首歌可以使用相同的名称,但这并不一定意味着它是同一张唱片。


是。


区分歌手的歌曲会更好吗?


它们由艺术家区分。

您确实知道,歌曲的事实和艺术家播放歌曲的事实是两个离散的事实,是吗?请质疑任何谓词,这些谓词都不是完全正确的,它们是数据库支持的命题。


Ave Maria作为独立事实存在于Song
Karen Carpenter, Celine Dion, and Yours Truly作为三个独立事实存在于Artist
Karen Carpenter-Ave Maria, Celine Dion-Ave Maria, and Yours Truly-Ave Maria作为ArtistSong.中的三个离散事实存在
那是七个独立的事实,大约一个Song,大约三个Artists.


对评论4的回应


我现在明白了。 artistong_table是2个“满足”和一个关系实际存在且唯一的位置。


是。我只是不会那样说。除了英文含义外,事实一词在技术上也有精确的含义。



数据库是有关现实世界的事实的集合,仅限于关注的主题领域。



考虑到对事实的理解,也许可以再次阅读我的回应3。


每个ArtistSong行都是事实。这取决于艺术家的事实和歌曲的事实。它建立了该歌手录制该歌曲的事实。而且ArtistSong事实是层次较低的其他事实所依赖的事实。
“关系……实际上”。我认为您的意思是“实例”。这些表之间存在关系,因为我画了一条线,您将实现外键约束。也许将事实视为“实例”。



只是为了确保我正确理解了这个想法,如果我要在混音中添加“流派”,那么我会以为会创建一个新的“独立”表genre_table,而artistong_table将其PK继承为FK是否正确?


是。这是经典的“引用”或“查找”表,“关系”将是非标识的。我对音乐妓院了解不多,无法发表任何声明,但是据我了解,流派适用于一首歌;一个艺术家;和ArtistSong(他们可以播放与Song.Genre不同的流派的歌曲)。您给了我一个,所以我会为它建模。

这样的结果是,当您在ArtistSong中插入行时,您将必须具有流派。如果这是供稿,那么很好,如果不是,那么您有处理上的问题要处理。解决该问题的简单方法是实现流派“”,该流向您指示您需要从其他渠道确定它。

稍后添加分类器(例如流派)很容易,因为它是非标识关系。但是,标识项很难在以后添加,因为它们会强制更改键。请参阅我的回应1下的第3段。

您可能已经准备好使用数据模型:

第三稿Music Chart Data Model

关于bash - 音乐图表跟踪器的SQLite数据库设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29929902/

相关文章:

sqlite - 如何在 Electron 应用程序中加密 SQLite DB?

bash - 从一系列 PDF 中删除第一页

c - 在 Shell 脚本或 Perl 脚本中对单词进行排序,然后对包含数字和字符的句子进行排序

bash - 两个文件的组合即时排序 View

sql-server - 应用程序服务器上需要 SET IDENTITY_INSERT ON/OFF,但 ALTER 权限似乎很危险。建议?

sql - 如何改进具有多个外键但实际上每次只使用其中一个键的表设计?

php - 与 Mysql 和 Propel 的额外字段和第四表外键的多对多关系

sql - SQLite3-如何在SQL表中定位特定值?

regex - 不是正则表达式中的运算符

python - 多个 SQLite 连接到 :memory: 中的数据库