我有点像菜鸟,所以我走了......
什么时候会有人使用键值(Redis,memcache等)商店进行网页开发?实际的用例最有帮助。
我的困惑在于,一个简单的数据库似乎功能更强大,因为根据我的理解,它可以完成键值存储所能做的所有事情PLUS它还允许您进行过滤/查询。这意味着,根据我的理解,您不能像使用键值存储一样进行过滤:select * homes where price > 100000
。
更新:
让我们让这个例子更真实。让我们假装StackOverflow使用键值存储(memcache,redis等)。
键值存储如何帮助Stackoverflow托管需求受益?
答案 0 :(得分:12)
我无法回答何时使用键值(此处为kv)数据存储的问题,但我可以向您展示一些示例,并回答您的stackoverflow示例。
通过数据库访问,您需要的大多数是kv商店。例如,用户使用用户名" joe"登录。所以你向上看"用户:乔"在您的数据库中并检索他的密码(当然是哈希)。或者也许你的密码在" user:pass:joe"下面,它确实无关紧要。如果它是堆栈溢出并且您正在呈现页面http://stackoverflow.com/questions/6935566/when-to-use-a-key-value-store-for-web-development
,那么您将查找"问题:6935566"并使用它。很容易看出kv商店如何解决你的大部分问题。
我想说kv商店是传统RDMS提供的功能的子集。这是因为传统RDMS的设计提供了许多扩展问题,并且在扩展时通常会丢失功能。 kv商店没有这些功能,所以他们不限制你。但是,通常可以创建这些功能,从核心设计可扩展(因为如果不是这样,它会立即变得明显)。
然而,这并不意味着有些事情是你无法做到的。例如,你提到查询。这是许多kv商店的陷阱,因为他们通常不知道价值(并非总是如此,例如,redis等),并且无法找到你想要的东西。更糟糕的是,它们的设计并不是为了快速实现,而是通过密钥快速查找。
此问题的一个解决方案是按字典顺序对键进行排序并允许范围查询。这基本上是#34;给我一切问题:1和问题:5"。现在这个例子相当无用,但范围查询有很多用途。
你说你希望所有的房子都超过10万美元。如果你想能够做到这一点,你可以按价格创建房屋指数。说你有以下房子。
house:0 -> {"color":"blue","sold":false,"city":"Stackoverville","price":500000}
house:1 -> {"color":"red","sold":true,"city":"Toronto","price":150000}
house:2 -> {"color":"beige","sold":false,"city":"Toronto","price":40000}
house:3 -> {"color":"blue","sold":false,"city":"The Blogosphere","price":110000}
在SQL中,您可以将每个字段存储在一列中,而不是将其全部放在一个(在本例中为JSON)文档中。可以SELECT * FROM houses WHERE price > 100000
。这似乎都很好,但是,如果没有建立索引,这需要查看表中的每个房子并检查其价格,如果你有几百万个房子,可能会很慢。因此,对于kv商店,您还需要一个索引。主要区别在于SQL数据库会默默地执行缓慢的操作,而kv存储将无法实现。
如果您没有范围查询,则需要将索引粘贴在单个文档中,这样可以安全地更新它,这意味着您必须为每个查询下载整个索引,同样限制可扩展性。
house:index:price -> [{"price":500000,"id":"0"},{"price":150000,"id":"1"},{"price":110000,"id":"3"},{"price":40000,"id":"2"}]
但是如果你有范围查询(通常称为键盘),你可以创建一个这样的索引:
house:index:price:040000 -> 2
house:index:price:110000 -> 3
house:index:price:150000 -> 1
house:index:price:500000 -> 0
然后你可以在house:index:price:100000
和house:index:price::
之间请求密钥(':'字符是' 9'之后的字符)得到[3,1,0]
这是所有的房子比10万美元更贵(他们也有帮助)。关于这一点的另一个好处是,他们可能会在一个"分区"你的群集,所以这个查询将花费大约相同的时间获得(加上微小的额外传输开销)或两个获取,如果你的范围碰巧越过服务器边界(但这些可以并行完成!)。
这样就显示了如何在kv商店中进行查询。您可以查询任何可以作为字符串排序的内容(几乎任何内容)并快速查找。如果您没有范围查询,则需要将整个索引存储在一个很糟糕的密钥下,但如果您有范围查询,则非常好,而且非常快。这是一个更复杂的例子。
我希望多伦多未售出的房屋价值低于10万美元。我只需要设计我的指数。 (我添加了几个房子以使其更有意义)首先想到你可能只为每个属性构建另一个索引,但你很快就会意识到这意味着你必须选择每个未售出的房子并从数据库下载它。 (当我说缩放问题很明显时,这就是我的意思。)解决方案是使用多索引。构建完成后,您可以精确选择所需的值。
house:index:sold:city:price:f~Fooville~000010:5 -> ""
house:index:sold:city:price:f~Toronto~040000:2 -> ""
house:index:sold:city:price:f~Toronto~140000:4 -> ""
house:index:sold:city:price:t~Stackoverville~500000:0 -> ""
house:index:sold:city:price:t~The Blogosphere~110000:3 -> ""
house:index:sold:city:price:t~Toronto~150000:1 -> ""
现在,与上一个示例不同,我将id放入密钥中。这允许两个房子具有相同的属性。我可以将它们合并到值中,但是添加删除索引变得更加困难。我还选择将数据与~
分开。这是因为它在所有字母之后按字典顺序排列,确保全名将被分类,并且我不必将每个城市填充到相同的长度。在生产系统中,我可能会使用255或0字节。
现在,house:index:sold:city:price:f~Toronto~100000
- house:index:sold:city:price:f~Toronto~~
范围将选择与查询匹配的所有房屋。需要注意的重要一点是查询与结果数量呈线性关系。这意味着您必须为要编制索引的每组属性构建索引(尽管我们示例中的索引也适用于已售出和已售出城市的查询)。这可能看起来像很多工作,但最后你意识到只是你在做,而不是你的数据库。我相信我们很快就会开始看到图书馆出现这种事情:D
稍微扩展一下话题后,我已经表明:
我认为您会发现kv-store对于许多应用程序来说足够了,并且通常可以提供比传统RDMS更好的性能和可用性。话虽如此,每个应用程序都是不同的,因此,回答原始问题是不可能的。
答案 1 :(得分:5)
不要将NoSQL类型数据库与memcached(不打算永久存储数据)混淆。
memcached的典型用途是存储一些可由Web服务器集群访问的查询结果 - 即。共享缓存。例如。在此页面上是相关帖子的列表,数据库可能需要做一些工作才能生成该列表。如果您每次有人加载页面时都这样做,那么您将为数据库创建大量工作。相反,第一次检索的结果可以存储在memcached服务器上,其中密钥是页面ID。然后,群集中的任何Web服务器都可以非常快速地获取该信息,而无需经常访问数据库。一段时间后,缓存条目将被memcached清除,以便旧文章的结果不会占用空间。 [免责声明:我不知道StackOverflow是否真的这样做了。)
另一方面,“NoSQL”数据库用于永久存储信息。如果您的数据模式非常简单,那么查询也是如此,那么它可能比标准SQL数据库更快。许多Web应用程序不需要非常复杂的数据库,因此NoSQL数据库非常适合。
答案 2 :(得分:4)
noSQL有两个一般可行的用例:
大多数noSQL解决方案实际上都没有架构的事实;要求运作的仪式少得多;重量轻(就API而言);与更规范的关系持久性系统相比,它提供了显着的性能提升,表明它们适用于上述两种用例(一般意义上)。
愤世嫉俗 - 或者在商业意义上可能是实用的 - 可以为noSQL系统提出第三个通用用例(仍然通过上述特征/功能集):
更容易受到伤害,任何没有经验的(但没有脑死亡的)极好的极客都可以随时捡起它。这是一个非常强大的功能。 (尝试使用Oracle ..)
因此,noSQL系统的用例 - 通常可以表征为宽松持久系统 - 都是通过实际考虑得到最佳信息的。
毫无疑问 - 在大规模可扩展系统之外 - RDBMS系统是用于确保数据完整性的正式完美系统。
答案 3 :(得分:3)
键值存储通常非常快,因此最好将它们作为高速访问且很少更新的数据的缓存,以减少数据库的负载。
正如您所说,您通常会受限于查询(尽管MongoDB处理得非常好),但键值存储主要用于访问精确数据:用户X的配置文件,会话X的信息等。< / p>
对于普通网站而言,“传统”数据库可能绰绰有余,但如果您遇到高负荷,键值存储可以真正帮助您加载时间。
编辑:“高负荷”,我的意思是真的高负荷。键值商店很少需要。
答案 4 :(得分:1)
只是增加了bstrawson的答案, “mem- 缓存 -d”是一种缓存机制,而Redis是永久存储,但都将数据存储为键值对。
搜索键值存储(类似Redis或Membase)更像是搜索关系数据库中的所有值,速度太慢。如果你想做一些查询,你可能需要转移到面向文档的NoSQL类型的数据库,如MongoDB或CouchDB,你可以做一些查询部分。
不久的将来,您将能够处理couchbase sever 2.0,它将解决使用新引入的UnQL和缓存(直接从memcached源代码派生)的NoSQL数据查询的所有问题
答案 5 :(得分:0)
Stack Overflow确实使用Redis,并且广泛使用。以问题为例,在a couple of nice blog posts中由@Mark Gravell提供问题的详细解答。 Mark是精湛的Booksleeve完全异步.NET Redis绑定库的作者。