SQL vs NoSQL:如何选择?
作者:网络转载 发布时间:[ 2015/10/9 13:22:05 ] 推荐标签:数据库
Schema是固定不变的
我们没有考虑到联系人的中间名字、出生日期、公司或职位。我们添加多少字段都没关系,我们很快会受到更新的需求要添加备注、纪念日、关系状态、社交媒体账号、内腿测量值、喜欢的奶酪类型等字段。预测所有选项是不可能的,因此我们可能需要一个 otherdata 表,用来处理名字-值对。
数据是碎片化的
对开发者或者系统管理员来说,检查数据库并不容易。程序逻辑会变得更慢、更复杂,因为利用单个 SELECT 和多个 JOIN 语句查询联系人数据不太实际。(你可以这么做,但是结果可能需要包含 telephone,email,和 address字段的每一种组合:如果有个联系人有三个电话号码,五个Email地址和两个住址,那么SQL查询将会产生30条结果。) 后,全文搜索很困难。如果有人输入字符串”SitePoint”,我们必须检查所有的表,看看它是否为联系人名字、电话、Email或者住址的一部分,并且需要做相应的排序。如果你用过WordPress的搜索功能,你会明白这有多虐心。
选择NoSQL
我们的联系人数据关注的是人。他们难以预测,在不同的时间有不同的需求。使用NoSQL数据库,联系人列表将会从中受益。数据库将一个联系人的所有数据存储在一个单独的文档里的contacts 集合里。
{
name: [
"Billy", "Bob", "Jones"
],
company: "Fake Goods Corp",
jobtitle: "Vice President of Data Management",
telephone: {
home: "0123456789",
mobile: "9876543210",
work: "2244668800"
},
email: {
personal: "bob@myhomeemail.net",
work: "bob@myworkemail.com"
},
address: {
home: {
line1: "10 Non-Existent Street",
city: "Nowhere",
country: "Australia"
}
},
birthdate: ISODate("1980-01-01T00:00:00.000Z"),
twitter: '@bobsfakeaccount',
note: "Don't trust this guy",
weight: "200lb",
photo: "52e86ad749e0b817d25c8892.jpg"}
在这个例子里,我们没有存储联系人的头衔或者性别,我们还添加了一些数据,而这些数据不需要应用到任何其他联系人。没关系——我们的NoSQL数据库不会介意,我们还可以随意添加或移除字段。
由于联系人数据在单独的文档里,我们可以用一条查询语句获取一部分或全部信息。全文搜索也变得简单;在MongoDB里,我们可以这样定义 contact 中的所有文本字段的索引:
db.contact.createIndex({ "$**": "text" });
然后执行全文搜索:
db.contact.find({
$text: { $search: "something" }});
场景二:社交网络
社交网络可能使用类似的联系人数据存储,但是它会根据功能集合扩展,比如关系链、状态更新、发送消息和”赞“。这些功能可能会根据用户需求来实现或者移除——无法预测它们会怎样演进。
另外:
大部分的数据更新都来自单个源:用户。任何时候我们不太可能同时更新两条或更多记录,因此不要求类似事务控制的功能。
尽管有些用户可能认为,状态更新失败不可能引起系统崩溃或经济损失。应用程序的接口和性能比数据完整性优先级更高。
NoSQL看来是个好的方案。它允许我们快速地实现存储不同类型数据的功能。例如,可以用单个文档里的 status 集合替换所有用户的过时的状态更新。
{
user_id: ObjectID("65f82bda42e7b8c76f5c1969"),
update: [
{
date: ISODate("2015-09-18T10:02:47.620Z"),
text: "feeling more positive today"
},
{
date: ISODate("2015-09-17T13:14:20.789Z"),
text: "spending far too much time here"
}
{
date: ISODate("2015-09-17T12:33:02.132Z"),
text: "considering my life choices"
}
]}
文档可能会变得很长,但我们可以获取数组的子集,比如近的更新。每个用户的所有的历史状态记录都能被快速搜索到。
现在假设我们想在发布更新的时候引入表情符号选择。这涉及到给 update 数组里的新记录添加图引用。不像 SQL 存储,没必要把之前消息里的表情符号置为 NULL——我们的程序逻辑可以显示默认图片或者没有图片,如果没有设置表情符号的话。
场景三:仓库管理系统
考虑一个监控仓库货物的系统。我们需要记录:
送达仓库并被分配到指定位置的物品
仓库内物品的移动,也是重新整理库存,以便让同样的物品放在相邻的位置
订单以及后续将物品搬出仓库,准备发货
我们的数据需求:
通用的物品信息,比如包装数量、尺寸和颜色等可被存储,但这些是我们可以识别并应用到任何物品上的离散数据。我们不太可能关注细节,例如笔记本处理器速度或者智能手机的电池寿命。
小化出错的可能是必要的。我们不能让物品凭空消失或者移到已经有别的物品存放的位置。
简单来说,我们在记录物品从一个物理区域到另一个物理区域的转移——或者从A位置移走,放到B位置。这是同一个动作的两次更新。
我们需要一个具备强制数据完整性和事务支持的健壮存储系统。(当前)只有 SQL 数据库满足这些需求。
表现自己!
我希望这些场景有所帮助,但是每个项目是不同的,终,你需要做出自己的决定。(虽然,我们开发人员擅长于证明我们的技术选择,不管他们有多好!)
好的建议:显露你自己尽可能多的技术。这些知识可以让你对SQL或者NoSQL做出一个理性和情感上公正的判断。祝您好运。
本文内容不用于商业目的,如涉及知识产权问题,请权利人联系SPASVO小编(021-61079698-8054),我们将立即处理,马上删除。

sales@spasvo.com