使用关系数据库与JSON对象获取事件/活动数据


28

我正在一个项目中尝试在一个标准SQL关系数据库或JSON对象之间存储有关事件或活动的数据。

该项目将存储多种事件类型的数据,因此我决定仅描述此问题的一种事件类型。

现场音乐事件(此问题底部使用JSON模式完整描述)是一个对象,用于存储数据,例如事件发生的地点,事件的时间/日期和事件的成本。现场音乐事件对象具有一对一(事件->名称,事件->描述)和一对多(事件->场所,事件->日期,事件->票证类型) )关系。此外,事件对象可以包含一个或多个执行者ID,这些ID链接到执行者对象。表演者对象存储有关在现场音乐事件中表演的音乐家的数据。

用户将使用简单数据(“以'x'名称为我查找事件”)和复杂数据(以'x'音乐体裁为'y'事件并在距我当前半径'z'范围内以'y'为代价的事件来查询数据)位置”)查询。数据将由用户使用Web表单提交。

从定义的JSON模式中可以看出,我本来打算使用JSON对象存储此数据,但是我听到有些人说,因为我的数据是纯关系型的,所以我应该坚持使用较旧的方法。

鉴于我的需要,我希望对每种方法的利弊有任何想法。如果您需要任何澄清,请随时询问。

{
    "event": {
        "eventID":{
            "type":"string"
        },  
        "eventType":{
            "type":"array",
            "eventTypeItem":{
                "type":"string"
            }
        },
        "eventName":{
            "type":"string"
        },      
        "eventDescription":{
            "type":"string"
        },
        "eventVenueList":{
            "type":"array",
            "eventVenueListID":{
                "type":"integer"
            }
        },
        "eventURL":{
            "type":"string"
        },
        "eventTwitter":{
            "type":"string"
        },
        "eventFB":{
            "type":"string"
        },
        "eventInstagram":{
            "type":"string"
        },
        "eventEmail":{
            "type":"string",
            "format":"email"
        },
        "eventContactPerson":{
            "type":"string"
        },
        "eventDoorTime": {
            "type":"string",
            "format":"date-time"
        },  
        "eventPerformerIDList":{
            "type":"array",
            "liveMusicPerformerID":{
                "type":"integer"
            }
        },  
        "eventSetList":{
            "type":"array",
            "eventPerformerID":{
                "type":"integer"
            },
            "eventPerformerStartTime":{
                "type":"string",
                "format":"date-time"
            },
            "eventPerformerEndTime":{
                "type":"string",
                "format":"date-time"
            }                                   
        },
        "eventDateList": {
            "type":"array",
            "eventDateItem": {
                "type":"string",
                "format":"date-time"
            }   
        },
        "eventDateStartTime": {
            "type":"string",
            "format":"date-time"
        },
        "eventDateEndTime": {
            "type":"string",
            "format":"date-time"
        },
        "eventTicket":{ 
            "type":"array",
            "eventTicketType":{
                "type":"string" 
            },
            "eventTicketLowPrice":{
                "type":"number"
            },
            "eventTicketHighPrice":{
                "type":"number" 
            },
            "eventDatesAdvancePrice": {
                "type":"number"
            }   
        }
    },  
    "performer": {
        "performerID": {
            "type":"integer"
        },
        "performerType": {
            "type":"string"
        },
        "performerName": {
            "type":"string"
        },
        "performerAlternateName": {
            "type":"array",
            "performerAlterateNameItem":{
                "type":"string"
            }
        },
        "performerGenreList": {
            "type":"array",
            "performerGenreItem":{
                "type":"string"
            }
        },
        "performerURL": {
            "type":"string"
        }                                       
    }
}   

我不知道场地的要求,但我想按以下条件搜索:表演者,地点以及可能的日期。因为它们被保存在数组类型中,这会成为问题吗?
JeffO 2014年

您是否可以对查询进行编程以搜索相关数组中的值?
zgall1 2014年

13
JSON不是存储格式。没错,您可以使用内容的文本文件存储数据,但只能在最简单的情况下进行。JSON比关系数据库“新”与您的决定没有任何关系。
罗伯特·哈维

1
我意识到这不是一种存储格式。我的意思是我可以使用MongoDB或Postgre的JSON对象以JSON格式存储数据。
zgall1 2014年

2
@RobertHarvey和选民,在当今(2017年)中,JSON 一种存储格式:请参见PostgreSQL 9.6+ ...从2012年开始为基础,从2015年末开始为专业且成熟(JSONb数据类型)。
彼得·克劳斯

Answers:


45

我认为您的问题确实可以归结为: 什么时候应该使用NoSQL方法而不是RDBMS? 您很早就决定使用JSON(这是NoSQL式的决定),也许是因为您有Ajax使用者。

当然,何时使用NoSQL方法与RDBMS的答案基本上是关于您正在使用的数据类型以及预期的消费者。如果您的数据本质上是关系型的(层次结构相当平坦,没有图像或音频之类的怪异数据类型,可以在键中轻松描述的模式之间可预测的关系),那么您的消费者最终将包括希望进行商业智能查询的人员(即席查询),那么RDBMS是必经之路。将查询转换为JSON表示非常容易,因此不会给您的Ajax使用者造成很大的负担,它只是向端点(REST / SOAP /任何东西)添加了一些转换编码。 反过来,如果您的数据是非常分层的(深层架构),包含图像,音频,视频等奇怪的数据类型,则实体之间的关系很少,并且您知道最终用户将不会使用BI,那么NoSQL /存储JSON可能合适。

当然,即使是这些通用指南也并非一成不变。Google之所以开发Google文件系统,MapReduce(Doug Cutting在Yahoo上用于构建Hadoop的工作)和后来的BigQuery(一种面向NoSQL的无模式管理大规模数据的方式)的原因,正是因为它们有很多临时性BI请求,他们无法获得相关方法来扩展到他们尝试管理的tera / peta / exa / zetta / yotta规模。唯一可行的方法是进行扩展,以牺牲RDBMS提供的一些即席查询用户友好性,并替换一个简单的算法(MapReduce),该算法可以很容易地为任何给定查询编码。

给定上面的模式,我的问题基本上是:为什么使用RDBMS?我没有太多理由不这样做。我们的职业应该是面向工程的,而不是面向时尚的,所以我们的本能应该是选择最可行的解决方案,对吗?我的意思是,如果您的消费者是Ajaxy,则您的端点可能需要做一些翻译,但是您的数据看起来非常平坦,而且业务用户似乎很想对音乐事件之类的内容进行各种即席查询(去年,距我们首都50英里以内的活动最多?

“不要向精灵寻求建议,因为他们会说“不”和“是”。-佛罗多


“我们的职业应该是面向工程的,而不是面向时尚的,所以我们的直觉应该是选择……”行之有效的最佳解决方案?;)
宾克

5

我相信您可能没有在这里寻找更多的注意事项。这里有两个主要问题:

  • 存储
  • 搜索和检索

存储

关于为什么对数据使用no-sql或RDBMS存储,有很多意见。我们认为有用的最重要的项目之一是,我们可以轻松地在存储中定义和存储json对象,而不必担心定义它的完整结构或不同类型的对象之间的关系。使用NoSql数据库的其他一些原因是能够自动分片数据,基于位置的搜索以及易于维护。有很多不错的NoSql数据库,我个人偏爱MongoDB。但是,如果您以前从未使用过NoSql数据库,则在学习重新连接思维时会有明确的学习曲线。我们大多数人已经使用RDBMS已有一段时间了,需要有意识的努力才能摆脱这种习惯。另外,您会发现自己想在继续努力的同时重做数据模型,并且对概念有更好的理解。如果重构或重塑功能不是您的项目的选择,我建议您坚持使用您最了解的知识。

搜索

如果您打算提供任何可用的搜索,我强烈建议您使用专用文本搜索引擎(例如SOLR)来执行搜索。文本搜索速度很慢,如果您有多个分片,则搜索速度会更慢。SOLR支持超快速文本搜索,包括加权搜索参数,基于位置的搜索等等。但是,SOLR不适合用作数据的主要存储。这确实意味着您将必须创建用于双重插入的机制,并在添加或更新事件时对主数据库和SOLR层进行更新。另外,您还必须通过删除所有过时/结束的事件来使SOLR保持更新。

尽管这似乎需要做很多额外的工作,但是您将感谢您以后使用全文搜索引擎的远见卓识。NoSql数据库或RDBMS都无法接近SOLR / Lucene的性能和敏捷性。


3

首先,如果你想存储 JSON数据在任何存储,但不是的NoSQL数据库,我肯定会阻止你使用JSON。原因是,例如,如果将数据存储为JSON文件,则打开,解析,循环遍历等将非常慢。

那就是说,我可以将您的问题缩小到:NoSQLRDBMS的优缺点是什么?并且它已经在网上被回答了数千次。

升级项目,您当然可以使用NoSQLRDBMS;但是,我通常向您推荐的是开箱即​​用的思维方式,并寻找其他可能帮助您在两个选项之间做出选择的不为人知的因素。尝试看看哪个选项可以加快开发速度?如果您不是唯一的开发人员,那么哪个更适合其他团队成员。如果您要出售这种产品,哪一种更便宜,更容易并且通常更适合您的非开发客户?

这样,您最终可以决定要走的路,否则,由于给定的两个选项都非常合适,因此很难根据给定的信息来确定。


2

在大多数应用中,有一些要求

  1. 输入数据,执行一些处理,保存数据,检索数据并查询数据。可能还需要生成有关数据的报告。
  2. 在系统的不同部分之间或与外部系统交换数据

为了达到第1项的要求,需要一种持久化数据的方法。通常,如果数据量很小并且数据类型很简单并且不需要广泛的搜索功能,则可以使用简单的文件结构。随着数据变得越来越复杂,可以使用XML(甚至JSON)结构,而数据仍存储在文件中。尽管搜索变得更加麻烦。随着数据量的增加和搜索复杂性的增加,通常会选择一个数据库,该数据库提供了用于数据持久性,查询等的行业标准方法。数据库可以设计为处理大量数据并快速有效地存储,检索和搜索数据。 。

为了达到第2项的要求,可以使用多种不同的方法来允许系统之间的数据交换,包括XML,JSON等。

这些方法允许用户定义数据结构,并且与语言无关,从而允许不同的系统交换数据。

在您的特定情况下,您正确使用了JSON,它描述了一组音乐事件。尽管您可以将数据存储为JSON格式,但随着音乐事件数量的增加而搜索该数据将变得缓慢且效率低下。

使用关注点分离方法,更好的方法是收集数据,存储在数据库中,基于数据库中的用户输入执行查询,然后将JSON格式的结果返回给客户端以显示数据。

JSON方法的另一个问题是数据结构不断变化。当前,您的结构相对简单。您可能会使用此结构几个月,然后再标识一个附加字段。您将如何处理所有现有的JSON对象?更新这些将是有问题的。

如果您使用的是数据库,那么添加一个额外的字段就相对简单了,只需要在一个地方修改生成JSON的代码,即可为您提供带有新字段的所有新JSON。

简而言之,每种技术都是针对JSON(用于数据交换)和Database(用于数据持久性)而设计的。


0

我认为,使用NoSQL会比使用SQL存储这些数据取得更好的成功,因为您需要执行查询。

同样,仅仅因为某些数据是纯粹的关系数据并不意味着它必须被持久化到某些RDBMS(SQL)中。IMO关系数据将更好地转换为图形数据库。

当然,您也可以用SQL编写查询,但是由于需要的联接数量,性能将变得很糟糕(考虑到数据将在某种程度上被规范化,而并非所有数据都放入一个Event表中)。

但是总而言之,考虑到将来您可以在不考虑已经持久化的数据的情况下修改架构,因此使用NoSQL(因此可以使用JSON或数据库支持的其他格式)将拥有更大的自由度。

考虑使用NoSQL,如果您打算使用非常复杂的查询,您还可以研究图形数据库,因为它们将为您带来轻松创建和快速执行它们的优势。


0

我认为您应该同时使用这两者,但我不认为这是“与”相对的决定。

关系数据库对于具有关系属性的数据的快速有效存储和检索是有意义的。

JSON是一种很好的数据格式,因为它简单,轻巧,并且非常适合以非常基本的格式传递原始数据,并采用适合于存储和交换文本信息的语法。这对于在浏览器和服务器之间传递少量数据非常有用。对于关系类型数据查询,开始使用这种格式并不容易。

因此,我建议将SQL用于数据存储,并将JSON用于数据传输格式。

的确,没有诸如Mongo,Redis等的SQL键值选项。它们的优点是可以更简单地映射到JSON格式,但通常更难用于查询。它们的主要障碍是普通IT社区不熟悉,特别是与众所周知的SQL相比,它几乎具有可想象的每种情况的大量资源和知识。


如果我要找到一个对如何在查询中使用noSQL键值存储方法有充分了解的程序员,那么您是否会说这是将JSON用作数据存储格式所要克服的最大挑战?
zgall1 2014年

我敢打赌,那是因为唯一的数据结构差/比平均值差。开发人员知道是关系数据库。不过,这与开发人员的平均素质有关,以及他们如何学会避免学习,NoSQL将是非关系数据的正确选择……事实上,每次,对于开发人员来说,这通常更简单,前提是您的数据确实是非关系的。但是您必须正确选择数据库,NoSQL是最初选择的成败..以及它与数据的匹配程度。
JM Becker 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.