<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Database | 酷 壳 - CoolShell</title>
	<atom:link href="https://coolshell.cn/tag/database/feed" rel="self" type="application/rss+xml" />
	<link>https://coolshell.cn</link>
	<description>享受编程和技术所带来的快乐 - Coding Your Ambition</description>
	<lastBuildDate>Tue, 15 May 2012 06:28:11 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.2</generator>
	<item>
		<title>NoSQL 数据建模技术</title>
		<link>https://coolshell.cn/articles/7270.html</link>
					<comments>https://coolshell.cn/articles/7270.html#comments</comments>
		
		<dc:creator><![CDATA[陈皓]]></dc:creator>
		<pubDate>Tue, 15 May 2012 00:22:13 +0000</pubDate>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[NoSQL]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://coolshell.cn/?p=7270</guid>

					<description><![CDATA[<p>全文译自墙外文章“NoSQL Data Modeling Techniques”，译得不好，还请见谅。这篇文章看完之后，你可能会对NoSQL的数据结构会有些感觉...</p>
<p class="read-more"><a class="btn btn-default" href="https://coolshell.cn/articles/7270.html"> Read More<span class="screen-reader-text">  Read More</span></a></p>
The post <a href="https://coolshell.cn/articles/7270.html">NoSQL 数据建模技术</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></description>
										<content:encoded><![CDATA[<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415450859608158"
     crossorigin="anonymous"></script>全文译自墙外文章“<a href="http://highlyscalable.wordpress.com/2012/03/01/nosql-data-modeling-techniques/" target="_blank">NoSQL Data Modeling Techniques</a>”，译得不好，还请见谅。这篇文章看完之后，你可能会对NoSQL的数据结构会有些感觉。我的感觉是，关系型数据库想把一致性，完整性，索引，CRUD都干好，NoSQL只干某一种事，但是牺牲了很多别的东西。总体来说，我觉得NoSQL更适合做Cache。下面是正文——</p>
<p>NoSQL 数据库经常被用作很多非功能性的地方，如，扩展性，性能和一致性的地方。这些NoSQL的特性在理论和实践中都正在被大众广泛地研究着，研究的热点正是那些和性能分布式相关的非功能性的东西，我们都知道 <a href="http://en.wikipedia.org/wiki/CAP_theorem">CAP 理论</a>被很好地应用于了 NoSQL 系统中（陈皓注：CAP即，一致性(Consistency)， 可用性(Availability)， 分区容忍性(Partition tolerance)，在分布式系统中，这三个要素最多只能同时实现两个，而NoSQL一般放弃的是一致性）。但在另一方面，NoSQL的数据建模技术却因为缺乏像关系型数据库那样的基础理论没有被世人很好地研究。这篇文章从数据建模方面对NoSQL家族进行了比较，并讨论几个常见的数据建模技术。</p>
<p>要开始讨论数据建模技术，我们不得不或多或少地先系统地看一下NoSQL数据模型的成长的趋势，以此我们可以了解一些他们内在的联系。下图是NoSQL家族的进化图，我们可以看到这样的进化：Key-Value时代，BigTable时代，Document时代，全文搜索时代，和Graph数据库时代：（陈皓注：注意图中SQL说的那句话，NoSQL再这样发展下去就是SQL了，哈哈。）</p>
<div id="attachment_310">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/overview2.png"><img decoding="async" loading="lazy" title="overview" src="https://coolshell.cn/wp-content/uploads/2012/05/overview2.png?w=594&amp;h=699" alt="" width="594" height="699" /><br />
</a>NoSQL Data Models</p>
</div>
<p>首先，我们需要注意的是SQL和关系型数据模型已存在了很长的时间，这种面向用户的自然性意味着：</p>
<p><span id="more-7270"></span></p>
<ul>
<li>最终用户一般更感兴趣于数据的聚合显示，而不是分离的数据，这主要通过SQL来完成。</li>
<li>我们无法通过人手工控制数据的并发性，完整性，一致性，或是数据类型校验这些东西的。这就是为什么SQL需要在事务，二维表结构（schema）和外表联合上做很多事。</li>
</ul>
<p>另一方面，SQL可以让软件应用程序在很多情况下不需要关心数据库的数据聚合，和数据完整性和有效性进行控制。而如果我们去除了数据一致性，完整性这些东西，会对性能和分布存储有着重的帮助。正因为如此，我们才有数据模型的进化：</p>
<ul>
<li><strong>Key-Value 键值对存储</strong>是非常简单而强大的。下面的很多技术基本上都是基于这个技术开始发展的。但是，Key-Value有一个非常致命的问题，那就是如果我们需要查找一段范围内的key。（陈皓注：学过hash-table数据结构的人都应该知道，hash-table是非序列容器，其并不像数组，链接，队列这些有序容器，我们可以控制数据存储的顺序）。于是，有序键值 （Ordered Key-Value） 数据模型被设计出来解决这一限制，来从根本上提高数据集的问题。</li>
</ul>
<ul>
<li><strong>Ordered Key-Value 有序键值</strong>模型也非常强大，但是，其也没有对Value提供某种数据模型。通常来说，Value的模型可以由应用负责解析和存取。这种很不方便，于是出现了 BigTable类型的数据库，这个数据模型其实就是map里有map，map里再套map，一层一层套下去，也就是层层嵌套的key-value（value里又是一个key-value），这种数据库的Value主要通过“列族”（column families），列，和时间戳来控制版本。（陈皓注：关于时间戳来对数据的版本控制主要是解决数据存储并发问题，也就是所谓的乐观锁，详见《<a title="多版本并发控制(MVCC)在分布式系统中的应用" href="https://coolshell.cn/articles/6790.html" target="_blank">多版本并发控制(MVCC)在分布式系统中的应用</a>》）</li>
</ul>
<ul>
<li><strong>Document databases 文档数据库</strong> 改进了 BigTable 模型，并提供了两个有意义的改善。第一个是允许Value中有主观的模式（scheme），而不是map套map。第二个是索引。 <strong>Full Text Search Engines 全文搜索引擎</strong>可以被看作是文档数据库的一个变种，他们可以提供灵活的可变的数据模式（scheme）以及自动索引。他们之间的不同点主要是，文档数据库用字段名做索引，而全文搜索引擎用字段值做索引。</li>
</ul>
<ul>
<li><strong>Graph data models 图式数据库</strong> 可以被认为是这个进化过程中从 Ordered Key-Value 数据库发展过来的一个分支。图式数据库允许构建议图结构的数据模型。它和文档数据库有关系的原因是，它的很多实现允许value可以是一个map或是一个document。</li>
</ul>
<h4> NoSQL 数据模型摘要</h4>
<p>本文剩下的章节将向你介绍数据建模的技术实现和相关模式。但是，在介绍这些技术之前，先来一段序言：</p>
<ul>
<li>NoSQL 数据模型设计一般从业务应用的具体数据查询入手，而不是数据间的关系：</li>
<ul>
<li>关系型的数据模型基本上是分析数据间的结构和关系。其设计理念是： ”<strong>What answers do I have?”</strong><em> </em></li>
<li>NoSQL 数据模型基本上是从应用对数据的存取方式入手，如：我需要支持某种数据查询。其设计理念是<strong> ”What questions do I have?”</strong></li>
</ul>
</ul>
<ul>
<li>NoSQL 数据模型设计比关系型数据库需要对数据结构和算法的更深的了解。在这篇文章中我会和大家说那些尽人皆知的数据结构，这些数据结构并不只是被NoSQL使用，但是对于NoSQL的数据模型却非常有帮助。</li>
</ul>
<ul>
<li>数据冗余和反规格化是一等公民。</li>
</ul>
<ul>
<li>关系型数据库对于处理层级数据和图式数据非常的不方便。NoSQL用来解决图式数据明显是一个非常好的解决方案，几乎所有的NoSQL数据库可以很强地解决此类问题。这就是为什么这篇文章专门拿出一章来说明层级数据模型。</li>
</ul>
<div>下面是NoSQL的分类表，也是我用来写这篇文章时做实践的产品：</div>
<div>
<ul>
<li>Key-Value 存储: Oracle Coherence, Redis, Kyoto Cabinet</li>
<li>类BigTable存储: Apache HBase, Apache Cassandra</li>
<li>文档数据库: MongoDB, CouchDB</li>
<li>全文索引: Apache Lucene, Apache Solr</li>
<li>图数据库: neo4j, FlockDB</li>
</ul>
</div>
<h4>概念技术 Conceptual Techniques</h4>
<p>这一节主要介绍NoSQL数据模型的基本原则。</p>
<h5>(1) 反规格化 Denormalization</h5>
<p>反规格化 Denormalization 可以被认为是把相同的数据拷贝到不同的文档或是表中，这样就可以简化和优化查询，或是正好适合用户的某中特别的数据模型。这篇文章中所说的绝大多数技术都或多或少地导向了这一技术。</p>
<p>总体来说，反规格化需要权衡下面这些东西：</p>
<ul>
<li><strong><em>查询数据量 /查询IO </em></strong> VS  <strong><em>总数据量</em></strong>。使用反规格化，一方面可以把一条查询语句所需要的所有数据组合起来放到一个地方存储。这意味着，其它不同不同查询所需要的相同的数据，需要放在别不同的地方。因此，这产生了很多冗余的数据，从而导致了数据量的增大。</li>
</ul>
<ul>
<li><strong><em>处理复杂度 </em></strong> VS <strong><em>总数据量</em></strong>. 在符合范式的数据模式上进行表连接的查询，很显然会增加了查询处理的复杂度，尤其对于分布式系统来说更是。反规格化的数据模型允许我们以方便查询的方式来存构造数据结构以简化查询复杂度。</li>
</ul>
<p><strong>适用性</strong>: Key-Value Store 键值对数据库， Document Databases文档数据库， BigTable风格的数据库。</p>
<h5>(2) 聚合 Aggregates</h5>
<p>所有类型的NoSQL数据库都会提供灵活的Schema（数据结构，对数据格式的限制）：</p>
<ul>
<li>Key-Value Stores 和 Graph Databases 基本上来说不会Value的形式，所以Value可以是任意格式。这样一来，这使得我们可以任意组合一个业务实体的keys。比如，我们有一个用户帐号的业务实体，其可以被如下这些key组合起来： <em>UserID_name, UserID_email, UserID_messages</em> 等等。如果一个用户没有email或message，那么相应也不会有这样的记录。</li>
</ul>
<ul>
<li>BigTable 模型通过列集合来支持灵活的Schema，我们称之为列族（<em>column family</em>）。BigTable还可以在同一记录上出现不同的版本（通过时间戳）。</li>
</ul>
<ul>
<li>Document databases 文档数据库是一种层级式的“去Schema”的存储，虽然有些这样的数据库允许检验需要保存的数据是否满足某种Schema。</li>
</ul>
<p>灵活的Schema允许你可以用一种嵌套式的内部数据方式来存储一组有关联的业务实体（陈皓注：类似于JSON这样的数据封装格式）。这样可以为我们带来两个好处。</p>
<ul>
<li>最小化“一对多”关系——可以通过嵌套式的方式来存储实体，这样可以少一些表联结。</li>
</ul>
<ul>
<li>可以让内部技术上的数据存储更接近于业务实体，特别是那种混合式的业务实体。可能存于一个文档集或是一张表中。</li>
</ul>
<div>下图示意了这两种好处。图中描给了电子商务中的商品模型（陈皓注：我记得我在“<a title="挑战无处不在" href="https://coolshell.cn/articles/7048.html" target="_blank">挑战无处不在</a>”一文中说到过电商中产品分类数据库设计的挑战）</div>
<div>
<ul>
<li>首先，所有的商品Product都会有一个ID，Price 和 Description。</li>
</ul>
<ul>
<li>然后，我们可以知道不同的类型的商品会有不同的属性。比如，作者是书的属性，长度是牛仔裤的属性。其些属性可能是“一对多”或是“多对多”的关系，如：唱片中的曲目。</li>
</ul>
<ul>
<li>接下来，我们知道，某些业务实体不可能使用固定的类型。如：牛仔裤的属性并不是所有的牌子都有的，而且，有些名牌还会搞非常特别的属性。</li>
</ul>
<p>对于关系型数据库来说，要设计这样的数据模型并不简单，而且设计出来的绝对离优雅很远很远。而我们NoSQL中灵活的Schema允许你使用一个聚合 Aggregate (product) 可以建出所有不同种类的商品和他们的不同的属性：</p>
</div>
<div>
<div id="attachment_404">
<p><a href="https://coolshell.cn/wp-content/uploads/2012/05/soft-schema2.png"><img decoding="async" loading="lazy" class="aligncenter" title="soft-schema" src="https://coolshell.cn/wp-content/uploads/2012/05/soft-schema2.png?w=594&amp;h=439" alt="" width="594" height="439" /></a></p>
<p style="text-align: center;">Entity Aggregation</p>
</div>
</div>
<div>
<p>上图中我们可以比较关系型数据库和NoSQL的差别。<strong>但是我们可以看到在数据更新上，非规格化的数据存储在性能和一致性上会有很大的影响，这就是我们需要重点注意和不得不牺牲的地方</strong>。</p>
</div>
<p><strong>适用性</strong>: Key-Value Store 键值对数据库， Document Databases文档数据库， BigTable风格的数据库。</p>
<h5>(3) 应用层联结 Application Side Joins</h5>
<p>表联结基本上不被NoSQL支持。正如我们前面所说的，NoSQL是“面向问题”而不是“面向答案”的，不支持表联结就是“面向问题”的后果。表的联结是在设计时被构造出来的，而不是在执行时建造出来的。所以，表联结在运行时是有很大开销的（陈皓注：搞过SQL表联结的都知道笛卡尔积是什么东西，大可以在参看以前酷壳的“<a title="图解SQL的Join" href="https://coolshell.cn/articles/3463.html" target="_blank">图解数据库表Joins</a>”），但是在使用了 Denormalization 和 Aggregates 技术后，我们基本不用进行表联结，如：你们使用嵌套式的数据实体。当然，如果你需要联结数据，你需要在应用层完成这个事。下面是几个主要的Use Case：</p>
<ul>
<li>多对多的数据实体关系——经常需要被连接或联结。</li>
</ul>
<ul>
<li>聚合 Aggregates 并不适用于数据字段经常被改变的情况。对此，我们需要把那些经常被改变的字段分到另外的表中，而在查询时我们需要联结数据。例如，我们有个Message系统可以有一个User实体，其包括了一个内嵌的Message实体。但是，如果用户不断在附加 message，那么，最好把message拆分到另一个独立的实体，但在查询时联结这User和Message这两个实体。如下图：</li>
</ul>
<p><a href="https://coolshell.cn/wp-content/uploads/2012/05/aggregates-joins.png"><img decoding="async" class="aligncenter" title="aggregates-joins" src="https://coolshell.cn/wp-content/uploads/2012/05/aggregates-joins.png?w=594" alt="" /></a></p>
<p><strong>适用性</strong>: Key-Value Store 键值对数据库， Document Databases文档数据库， BigTable风格的数据库， Graph Databases 图数据库。</p>
<h4>通用建模技术 General Modeling Techniques</h4>
<p>在本书中，我们将讨论NoSQL中各种不同的通用的数据建模技术。</p>
<h5>(4) 原子聚合 Atomic Aggregates</h5>
<p>很多NoSQL的数据库（并不是所有）在事务处理上都是短板。在某些情况下，他们可以通过分布式锁技术或是<a title="Implementation of MVCC Transactions for Key-Value Stores" href="http://highlyscalable.wordpress.com/2012/01/07/mvcc-transactions-key-value/" target="_blank">应用层管理的MVCC技术</a>来实现其事务性（陈皓注：可参看本站的“<a title="多版本并发控制(MVCC)在分布式系统中的应用" href="https://coolshell.cn/articles/6790.html">多版本并发控制(MVCC)在分布式系统中的应用</a>”）但是，通常来说只能使用聚合Aggregates技术来保证一些ACID原则。</p>
<p>这就是为什么我们的关系型数据库需要有强大的事务处理机制——因为关系型数据库的数据是被规格化存放在了不同的地方。所以，Aggregates聚合允许我们把一个业务实体存成一个文档、存成一行，存成一个key-value，这样就可以原子式的更新了：</p>
<div id="attachment_409">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/atomic-aggregate1.png"><img decoding="async" class="aligncenter" title="atomic-aggregate" src="https://coolshell.cn/wp-content/uploads/2012/05/atomic-aggregate1.png?w=594" alt="" /><br />
</a>Atomic Aggregates</p>
</div>
<p>当然，原子聚合 Atomic Aggregates 这种数据模型并不能实现完全意义上的事务处理，但是如果支持原子性，锁，或 test-and-set 指令，那么， Atomic Aggregates 是可以适用的。</p>
<p><strong><strong>适用性</strong>: </strong>Key-Value Store 键值对数据库， Document Databases文档数据库， BigTable风格的数据库。</p>
<h5>(5) 可枚举键 Enumerable Keys</h5>
<p>也许，对于无顺序的Key-Value最大的好处是业务实体可以被容易地hash以分区在多个服务器上。而排序了的key会把事情搞复杂，但是有些时候，一个应用能从排序key中获得很多好处，就算是数据库本身不提供这个功能。让我们来思考下email消息的数据模型：</p>
<ol>
<li>一些NoSQL的数据库提供原子计数器以允许生一些连续的ID。在这种情况下，我们可以使用 <em>userID_messageID</em> 来做为一个组合key。如果我们知道最新的message ID，就可以知道前一个message，也可能知道再前面和后面的Message。</li>
<li>Messages可以被打包。比如，每天的邮件包。这样，我们就可以对邮件按指定的时间段来遍历。</li>
</ol>
<p><strong><strong><strong>适用性</strong>: </strong></strong>Key-Value Store 键值对数据库<strong>。</strong></p>
<h5>(6) 降维 Dimensionality Reduction</h5>
<p>Dimensionality Reduction 降维是一种技术可以允许把一个多维的数据映射成一个Key-Value或是其它非多给的数据模型。</p>
<p>传统的地理位置信息系统使用一些如“四分树<a href="http://en.wikipedia.org/wiki/Quadtree" target="_blank">QuadTree</a>” 或 “<a href="http://en.wikipedia.org/wiki/R-tree" target="_blank">R-Tree</a>” 来做地理位置索引。这些数据结构的内容需要被在适当的位置更新，并且，如果数据量很大的话，操作成本会很高。另一个方法是我们可以遍历一个二维的数据结构并把其扁平化成一个列表。一个众所周知的例子是<a href="http://en.wikipedia.org/wiki/Geohash" target="_blank">Geohash</a>（地理哈希）。一个Geohash使用“之字形”的路线扫描一个2维的空间，而且遍历中的移动可以被简单地用0和1来表示其方向，然后在移动的过程中产生0/1串。下图展示了这一算法：（陈皓注：先把地图分成四份，经度为第一位，纬度为第二位，于是左边的经度是0，右边的是1，纬度也一样，上面是为1，下面的为0，这样，经纬度就可以组合成01，11，00，10这四个值，其标识了四块区域，我们可以如此不断的递归地对每个区域进行四分，然后可以得到一串1和0组成的字串，然后使用0-9，b-z 去掉（去掉a, i, l, o）这32个字母进行base32编码得到一个8个长度的编码，这就是Geohash的算法）</p>
<div id="attachment_398">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/geohash-traversal1.png"><img decoding="async" title="geohash-traversal" src="https://coolshell.cn/wp-content/uploads/2012/05/geohash-traversal1.png?w=594" alt="" /><br />
</a>Geohash Index</p>
</div>
<p>Geohash的最强大的功能是使用简单的位操作就可以知道两个区域间的距离，就像图中所示（陈皓：proximity框着的那两个，这个很像IP地址了）。Geohash把一个二维的坐标生生地变成了一个一维的数据模型，这就是降维技术。BigTable的降维技术参看到文章后面的 [6.1]。更多的关于Geohash和其它技术可以参看 [6.2] 和 [6.3]。</p>
<p><strong><strong><strong>适用性</strong>:</strong></strong> Key-Value Store 键值对数据库， Document Databases文档数据库， BigTable风格的数据库。</p>
<h5>(7) 索引表 Index Table</h5>
<p>Index Table 索引表是一个非常直白的技术，其可以你在不支持索引的数据库中得到索引的好处。BigTable是这类最重要的数据库。这需要我们维护一个有相应存取模式的特别表。例如，我们有一个主表存着用户帐号，其可以被UserID存取。某查询需要查出某个城市里所有的用户，于是我们可以加入一张表，这张表用城市做主键，所有和这个城市相关的UserID是其Value，如下所示：</p>
<div id="attachment_399">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/index-table.png"><img decoding="async" title="index-table" src="https://coolshell.cn/wp-content/uploads/2012/05/index-table.png?w=594" alt="" /><br />
</a>Index Table Example</p>
</div>
<p>可见，城市索引表的需要和对主表用户表保持一致性，因此，主表的每一个更新可能需要对索引表进行更新，不然就是一个批处理更新。无论哪个方式，这都会损伤一些性能，因为需要保持一致性。</p>
<p>Index Table 索引表可以被认为是关系型数据库中的视图的等价物。</p>
<p><strong>适用性</strong>: BigTable 数据库。</p>
<h5>(8) 键组合索引 Composite Key Index</h5>
<p>Composite key 键组合是一个很常用的技术，对此，当我们的数据库支持键排序时能得到极大的好处。Composite key组合键的拼接成为第二排序字段可以让你构建出一种多维索引，这很像我们之前说过的 Dimensionality Reduction 降维技术。例如，我们需要存取用户统计。如果我们需要根据不同的地区来统计用户的分布情况，我们可以把Key设计成这样的格式 <em>(State:City:UserID)</em>，这样一来，就使得我们可以通过State到City来按组遍历用户，特别是我们的NoSQL数据库支持在key上按区查询（如：BigTable类的系统）：</p>
<pre data-enlighter-language="sql" class="EnlighterJSRAW">SELECT Values WHERE state=&quot;CA:*&quot;
SELECT Values WHERE city=&quot;CA:San Francisco*&quot;</pre>
<div id="attachment_477">
<p style="text-align: center;"><a href="http://highlyscalable.files.wordpress.com/2012/03/composite-key-index.png"><img decoding="async" title="composite-key-index" src="http://highlyscalable.files.wordpress.com/2012/03/composite-key-index.png?w=594" alt="" /><br />
</a>Composite Key Index</p>
</div>
<p><strong><strong>适用性</strong>: </strong>BigTable 数据库。</p>
<h5>(9) 键组合聚合 Aggregation with Composite Keys</h5>
<p>Composite keys  键组合技术并不仅仅可以用来做索引，同样可以用来区分不用的类型的数据以支持数据分组。考虑一个例子，我们有一个海量的日志数组，这个日志记录了互联网上的用户的访问来源。我们需要计算从某一网站过来的独立访客的数量，在关系型数据库中，我们可能需要下面这样的SQL查询语句：</p>
<p><code data-enlighter-language="sql" class="EnlighterJSRAW">SELECT count(distinct(user_id)) FROM clicks GROUP BY site</code></p>
<p>我们可以在NoSQL中建立如下的数据模型：</p>
<div id="attachment_383">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/composite-key-collating1.png"><img decoding="async" title="composite-key-collating" src="https://coolshell.cn/wp-content/uploads/2012/05/composite-key-collating1.png?w=594" alt="" /><br />
</a>Counting Unique Users using Composite Keys</p>
</div>
<p>这样，我们就可以把数据按UserID来排序，我们就可以很容易把同一个用户的数据（一个用户并不会产生太多的event）进行处理，去掉那些重复的站点（使用hash table或是别的什么）。另一个可选的技术是，我们可以对每一个用户建立一个数据实体，然后把其站点来源追加到这个数据实体中，当然，这样一来，数据的更新在性能相比之下会有一定损失。</p>
<p><strong><strong>适用性</strong>:</strong> Ordered Key-Value Store 排序键值对数据库， BigTable风格的数据库。</p>
<p><strong><br />
</strong></p>
<h5>(10) 反转搜索 Inverted Search – 直接聚合 Direct Aggregation</h5>
<p>这个技术更多的是数据处理技术，而不是数据建模技术。尽管如此，这个技术还是会影响数据模型。这个技术最主要的想法是使用一个索引来找到满足某条件的数据，但是把数据聚合起需要使用全文搜索。还是让我们来说一个示例。还是用上面那个例子，我们有很多的日志，其中包括互联网用户和他们的访问来源。让我们假定每条记录都有一个UserID，还有用户的种类 (Men, Women, Bloggers, 等)，以及用户所在的城市，和访问过的站点。我们要干的事是，为每个用户种类找到满足某些条件（访问源，所在城市，等）的的独立用户。</p>
<p>很明显，我们需要搜索那些满足条件的用户，如果我们使用反转搜索，这会让我们把这事干得很容易，如： <em>{Category -&gt; [user IDs]}</em> 或 <em>{Site -&gt; [user IDs]}</em>。使用这样的索引， 我们可以取两个或多个UserID要的交集或并集（这个事很容易干，而且可以干得很快，如果这些UserID是排好序的）。但是，我们要按用户种类来生成报表会变得有点麻烦，因为我们用语句可能会像下面这样</p>
<p><code data-enlighter-language="sql" class="EnlighterJSRAW">SELECT count(distinct(user_id)) ... GROUP BY category</code></p>
<p>但这样的SQL很没有效率，因为category数据太多了。为了应对这个问题，我们可以建立一个直接索引 <em>{UserID -&gt; [Categories]}</em> 然后我们用它来生成报表：</p>
<div id="attachment_388">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/invert-direct1.png"><img decoding="async" loading="lazy" title="invert-direct" src="https://coolshell.cn/wp-content/uploads/2012/05/invert-direct1.png?w=594&amp;h=438" alt="" width="594" height="438" /><br />
</a>Counting Unique Users using Inverse and Direct Indexes</p>
</div>
<p>最后，我们需要明白，对每个UserID的随机查询是很没有效率的。我们可以通过批查询处理来解决这个问题。这意味着，对于一些用户集，我们可以进行预处理（不同的查询条件）。</p>
<p><strong>适用性</strong>: Key-Value Store 键值对数据库， Document Databases文档数据库， BigTable风格的数据库。</p>
<h4>层级式模型 Hierarchy Modeling Techniques</h4>
<h5>(11) 树形聚合Tree Aggregation</h5>
<p>树形或是任意的图（需反规格化）可以被直接打成一条记录或文档存放。</p>
<ul>
<li>当树形结构被一次性取出时这会非常有效率（如：我们需要展示一个blog的树形评论）</li>
<li>搜索和任何存取这个实体都会存在问题。</li>
<li>对于大多数NoSQL的实现来说，更新数据都是很不经济的（相比起独立结点来说）</li>
</ul>
<div id="attachment_381">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/tree-aggregation.png"><img decoding="async" title="tree-aggregation" src="https://coolshell.cn/wp-content/uploads/2012/05/tree-aggregation.png?w=594" alt="" /><br />
</a>Tree Aggregation</p>
</div>
<p><strong>适用性</strong>: Key-Value 键值对数据库, Document Databases 文档数据库</p>
<h5>(12) 邻接列表 Adjacency Lists</h5>
<p>Adjacency Lists 邻接列表是一种图 &#8211; 每一个结点都是一个独立的记录，其包含了 所有的父结点或子结点。这样，我们就可以通过给定的父或子结点来进行搜索。当然，我们需要通过hop查询遍历图。这个技术在广度和深度查询，以及得到某个结点的子树上没有效率。</p>
<p><strong>适用性</strong>: Key-Value 键值对数据库, Document Databases 文档数据库</p>
<p><strong><br />
</strong></p>
<h5>(13) Materialized Paths</h5>
<p>Materialized Paths 可以帮助避免递归遍历（如：树形结构）。这个技术也可以被认为是反规格化的一种变种。其想法是为每个结点加上父结点或子结点的标识属性，这样就可以不需要遍历就知道所有的后裔结点和祖先结点了：</p>
<div id="attachment_372">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/materialized-paths2.png"><img decoding="async" title="materialized-paths" src="https://coolshell.cn/wp-content/uploads/2012/05/materialized-paths2.png?w=594" alt="" /><br />
</a>Materialized Paths for eShop Category Hierarchy</p>
</div>
<p>这个技术对于全文搜索引擎来说非常有帮助，因为其可以允许把一个层级结构转成一个文档。上面的示图中我们可以看到所有的商品或<em>Men’s Shoes</em>下的子分类可以被一条很短的查询语句处理——只需要给定个分类名。</p>
<p>Materialized Paths 可以存储一个ID的集合，或是一堆ID拼出的字符串。后者允许你通过一个正则表达式来搜索一个特定的分支路径。下图展示了这个技术（分支的路径包括了结点本身）：</p>
<div id="attachment_377">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/materialized-paths-2.png"><img decoding="async" title="materialized-paths-2" src="https://coolshell.cn/wp-content/uploads/2012/05/materialized-paths-2.png?w=594" alt="" /><br />
</a>Query Materialized Paths using RegExp</p>
</div>
<p><strong>适用性</strong>: Key-Value 键值对数据库, Document Databases 文档数据, Search Engines 搜索引擎</p>
<h5>(14) 嵌套集 Nested Sets</h5>
<p><a href="http://en.wikipedia.org/wiki/Nested_set_model">Nested sets</a> 嵌套集是树形结构的标准技术。它被广泛地用在了关系性数据库中，它完全地适用于 Key-Value 键值对数据库 和 Document Databases 文档数据库。这个技术的想法是把叶子结点存储成一个数组，并通过使用索引的开始和结束来映射每一个非叶子结点到一个叶子结点集，就如下图所示一样：</p>
<div id="attachment_360">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/nested-sets.png"><img decoding="async" title="nested-sets" src="https://coolshell.cn/wp-content/uploads/2012/05/nested-sets.png?w=594" alt="" /><br />
</a>Modeling of eCommerce Catalog using Nested Sets</p>
</div>
<p>这样的数据结构对于immutable data不变的数据 有非常不错的效率，因为其点内存空间小，并且可以很快地找出所有的叶子结点而不需要树的遍历。尽管如此，在插入和更新上需要很高的性能成本，因为新的叶子结点需要大规模地更新索引。</p>
<p><strong>适用性</strong>: Key-Value Stores 键值数据库, Document Databases 文档数据库</p>
<h4>(15) 嵌套文档扁平化：有限的字段名 Nested Documents Flattening: Numbered Field Names</h4>
<p>搜索引擎基本上来说和扁平文档一同工作，如：每一个文档是一个扁平的字段和值的例表。这种数据模型的用来把业务实体映射到一个文本文档上，如果你的业务实体有很复杂的内部结构，这可能会变得很有挑战。一个典型的挑战是把一个有层级的文档映映射出来。例如，文档中嵌套另一个文档。让我们看看下面的示例：</p>
<div id="attachment_363">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/nested-documents-1.png"><img decoding="async" title="nested-documents-1" src="https://coolshell.cn/wp-content/uploads/2012/05/nested-documents-1.png?w=594" alt="" /><br />
</a>Nested Documents Problem</p>
</div>
<p>上面的每一个业务实体代码一种简历。其包括了人名和一个技能列表。我把这个层级文档映射成一个文本文档，一种方法是创建 <em>Skill</em> 和 <em>Level</em> 字段。这个模型可以通过技术或是等级来搜索一个人，而上图标注的那样的组合查询则会失败。（陈皓注：因为分不清Excellent是否是Math还是Poetry上的）</p>
<p>在引用中的 [4.6] 给出了一种解决方案。其为每个字段都标上数字 <em>Skill_i</em> 和 <em>Level_i</em>，这样就可以分开搜索每一个对（下图中使用了OR来遍历查找所有可能的字段）:</p>
<div id="attachment_365">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/nested-documents-3.png"><img decoding="async" title="nested-documents-3" src="https://coolshell.cn/wp-content/uploads/2012/05/nested-documents-3.png?w=594" alt="" /><br />
</a>Nested Document Modeling using Numbered Field Names</p>
</div>
<p>这样的方式根本没有扩展性，对于一些复杂的问题来说只会让代码复杂度和维护工作变大。</p>
<p><strong>适用性</strong>: Search Engines 全文搜索</p>
<h5>(16)嵌套文档扁平化：邻近查询 Nested Documents Flattening: Proximity Queries</h5>
<p>在附录 [4.6]中给出了这个技术用来解决扁平层次文档。它用邻近的查询来限制可被查询的单词的范围。下图中，所有的技能和等级被放在一个字段中，叫 SkillAndLevel，查询中出现的 “Excellent” 和 “Poetry” 必需一个紧跟另一个：</p>
<div id="attachment_364">
<p style="text-align: center;"><a href="https://coolshell.cn/wp-content/uploads/2012/05/nested-documents-2.png"><img decoding="async" title="nested-documents-2" src="https://coolshell.cn/wp-content/uploads/2012/05/nested-documents-2.png?w=594" alt="" /><br />
</a>Nested Document Modeling using Proximity Queries</p>
</div>
<p>附录 [4.3] 中讲述了这个技术被用在Solr中的一个成功案例。</p>
<p><strong>适用性</strong>: Search Engines 全文搜索</p>
<h5>(17) 图结构批处理 Batch Graph Processing</h5>
<p>Graph databases 图数据库，如 neo4j 是一个出众的图数据库，尤其是使用一个结点来探索邻居结点，或是探索两个或少量结点前的关系。但是处理大量的图数据是很没有效率的，因为图数据库的性能和扩展性并不是其目的。分布式的图数据处理可以被 MapReduce 和 Message Passing pattern 来处理。如： <a title="MapReduce Patterns, Algorithms, and Use Cases" href="http://highlyscalable.wordpress.com/2012/02/01/mapreduce-patterns/">在我前一篇的文章中的那个示例</a>。这个方法可以让 Key-Value stores, Document databases, 和 BigTable-style databases 适合于处理大图。</p>
<p><strong>Applicability</strong>: Key-Value Stores, Document Databases, BigTable-style Databases</p>
<h4>参考</h4>
<p>Finally, I provide a list of useful links related to NoSQL data modeling:</p>
<ol>
<li>Key-Value Stores:
<ol>
<li><a href="http://www.devshed.com/c/a/MySQL/Database-Design-Using-KeyValue-Tables/">http://www.devshed.com/c/a/MySQL/Database-Design-Using-KeyValue-Tables/</a></li>
<li><a href="http://antirez.com/post/Sorting-in-key-value-data-model.html">http://antirez.com/post/Sorting-in-key-value-data-model.htm</a>l</li>
<li><a href="http://stackoverflow.com/questions/3554169/difference-between-document-based-and-key-value-based-databases">http://stackoverflow.com/questions/3554169/difference-between-document-based-and-key-value-based-databases</a></li>
<li><a href="http://dbmsmusings.blogspot.com/2010/03/distinguishing-two-major-types-of_29.html">http://dbmsmusings.blogspot.com/2010/03/distinguishing-two-major-types-of_29.html</a></li>
</ol>
</li>
<li>BigTable-style Databases:
<ol>
<li><a href="http://www.slideshare.net/ebenhewitt/cassandra-datamodel-4985524">http://www.slideshare.net/ebenhewitt/cassandra-datamodel-4985524</a></li>
<li><a href="http://www.slideshare.net/mattdennis/cassandra-data-modeling">http://www.slideshare.net/mattdennis/cassandra-data-modeling</a></li>
<li><a href="http://nosql.mypopescu.com/post/17419074362/cassandra-data-modeling-examples-with-matthew-f-dennis">http://nosql.mypopescu.com/post/17419074362/cassandra-data-modeling-examples-with-matthew-f-dennis</a></li>
<li><a href="http://s-expressions.com/2009/03/08/hbase-on-designing-schemas-for-column-oriented-data-stores/">http://s-expressions.com/2009/03/08/hbase-on-designing-schemas-for-column-oriented-data-stores/</a></li>
<li><a href="http://jimbojw.com/wiki/index.php?title=Understanding_Hbase_and_BigTable">http://jimbojw.com/wiki/index.php?title=Understanding_Hbase_and_BigTable</a></li>
</ol>
</li>
<li>Document Databases:
<ol>
<li><a href="http://www.slideshare.net/mongodb/mongodb-schema-design-richard-kreuters-mongo-berlin-preso">http://www.slideshare.net/mongodb/mongodb-schema-design-richard-kreuters-mongo-berlin-preso</a></li>
<li><a href="http://www.michaelhamrah.com/blog/2011/08/data-modeling-at-scale-mongodb-mongoid-callbacks-and-denormalizing-data-for-efficiency/">http://www.michaelhamrah.com/blog/2011/08/data-modeling-at-scale-mongodb-mongoid-callbacks-and-denormalizing-data-for-efficiency/</a></li>
<li><a href="http://seancribbs.com/tech/2009/09/28/modeling-a-tree-in-a-document-database/">http://seancribbs.com/tech/2009/09/28/modeling-a-tree-in-a-document-database/</a></li>
<li><a href="http://www.mongodb.org/display/DOCS/Schema+Design">http://www.mongodb.org/display/DOCS/Schema+Design</a></li>
<li><a href="http://www.mongodb.org/display/DOCS/Trees+in+MongoDB">http://www.mongodb.org/display/DOCS/Trees+in+MongoDB</a></li>
<li><a href="http://blog.fiesta.cc/post/11319522700/walkthrough-mongodb-data-modeling">http://blog.fiesta.cc/post/11319522700/walkthrough-mongodb-data-modeling</a></li>
</ol>
</li>
<li>Full Text Search Engines:
<ol>
<li><a href="http://www.searchworkings.org/blog/-/blogs/query-time-joining-in-lucene">http://www.searchworkings.org/blog/-/blogs/query-time-joining-in-lucene</a></li>
<li><a href="http://www.lucidimagination.com/devzone/technical-articles/solr-and-rdbms-basics-designing-your-application-best-both">http://www.lucidimagination.com/devzone/technical-articles/solr-and-rdbms-basics-designing-your-application-best-both</a></li>
<li><a href="http://blog.griddynamics.com/2011/07/solr-experience-search-parent-child.html">http://blog.griddynamics.com/2011/07/solr-experience-search-parent-child.html</a></li>
<li><a href="http://www.lucidimagination.com/blog/2009/07/18/the-spanquery/">http://www.lucidimagination.com/blog/2009/07/18/the-spanquery/</a></li>
<li><a href="http://blog.mgm-tp.com/2011/03/non-standard-ways-of-using-lucene/">http://blog.mgm-tp.com/2011/03/non-standard-ways-of-using-lucene/</a></li>
<li><a href="http://www.slideshare.net/MarkHarwood/proposal-for-nested-document-support-in-lucene">http://www.slideshare.net/MarkHarwood/proposal-for-nested-document-support-in-lucene</a></li>
<li><a href="http://mysolr.com/tips/denormalized-data-structure/">http://mysolr.com/tips/denormalized-data-structure/</a></li>
<li><a href="http://sujitpal.blogspot.com/2010/10/denormalizing-maps-with-lucene-payloads.html">http://sujitpal.blogspot.com/2010/10/denormalizing-maps-with-lucene-payloads.html</a></li>
<li><a href="http://java.dzone.com/articles/hibernate-search-mapping-entit">http://java.dzone.com/articles/hibernate-search-mapping-entit</a></li>
</ol>
</li>
<li>Graph Databases:
<ol>
<li><a href="http://docs.neo4j.org/chunked/stable/tutorial-comparing-models.html">http://docs.neo4j.org/chunked/stable/tutorial-comparing-models.html</a></li>
<li><a href="http://blog.neo4j.org/2010/03/modeling-categories-in-graph-database.html">http://blog.neo4j.org/2010/03/modeling-categories-in-graph-database.html</a></li>
<li><a href="http://skillsmatter.com/podcast/nosql/graph-modelling">http://skillsmatter.com/podcast/nosql/graph-modelling</a></li>
<li><a href="http://www.umiacs.umd.edu/%7Ejimmylin/publications/Lin_Schatz_MLG2010.pdf">http://www.umiacs.umd.edu/~jimmylin/publications/Lin_Schatz_MLG2010.pdf</a></li>
</ol>
</li>
<li>Demensionality Reduction:
<ol>
<li><a href="http://www.slideshare.net/mmalone/scaling-gis-data-in-nonrelational-data-stores">http://www.slideshare.net/mmalone/scaling-gis-data-in-nonrelational-data-stores</a></li>
<li><a href="http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves">http://blog.notdot.net/2009/11/Damn-Cool-Algorithms-Spatial-indexing-with-Quadtrees-and-Hilbert-Curves</a></li>
<li><a href="http://www.trisis.co.uk/blog/?p=1287">http://www.trisis.co.uk/blog/?p=1287</a></li>
</ol>
</li>
</ol>
<p>（全文完）<!--



<p align="center"><a href= target=_blank><img decoding="async" src=""></a></p>





<p align="center"><img decoding="async" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.weixin.jpg"> <img decoding="async" loading="lazy" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.mini_.jpg" width="300" height="300"> <br />关注CoolShell微信公众账号和微信小程序</p>

 

--></p>
<div style="margin-top: 15px; font-size: 16px;color: #cc0000;">
<p align="center"><strong>（转载本站文章请注明作者和出处 <a href="https://coolshell.cn/">酷 壳 &#8211; CoolShell</a> ，请勿用于任何商业用途）</strong></p>
</div>

<div class="wp_rp_wrap  wp_rp_vertical_m" id="wp_rp_first"><div class="wp_rp_content"><h3 class="related_post_title">相关文章</h3><ul class="related_post wp_rp"><li ><a href="https://coolshell.cn/articles/1889.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2009/12/sql.where_.clause-150x150.jpg" alt="SQL的Where语句" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1889.html" class="wp_rp_title">SQL的Where语句</a></li><li ><a href="https://coolshell.cn/articles/8711.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/12/200906020837401710-150x150.jpg" alt="程序员疫苗：代码注入" width="150" height="150" /></a><a href="https://coolshell.cn/articles/8711.html" class="wp_rp_title">程序员疫苗：代码注入</a></li><li ><a href="https://coolshell.cn/articles/7490.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/06/f1-150x150.jpg" alt="性能调优攻略" width="150" height="150" /></a><a href="https://coolshell.cn/articles/7490.html" class="wp_rp_title">性能调优攻略</a></li><li ><a href="https://coolshell.cn/articles/6639.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/02/programming-language-150x150.jpg" alt="千万别惹程序员 " width="150" height="150" /></a><a href="https://coolshell.cn/articles/6639.html" class="wp_rp_title">千万别惹程序员 </a></li><li ><a href="https://coolshell.cn/articles/5826.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/26.jpg" alt="千万别用MongoDB？真的吗？！" width="150" height="150" /></a><a href="https://coolshell.cn/articles/5826.html" class="wp_rp_title">千万别用MongoDB？真的吗？！</a></li><li ><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/7.jpg" alt="开源中最好的Web开发的资源" width="150" height="150" /></a><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_title">开源中最好的Web开发的资源</a></li></ul></div></div>The post <a href="https://coolshell.cn/articles/7270.html">NoSQL 数据建模技术</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></content:encoded>
					
					<wfw:commentRss>https://coolshell.cn/articles/7270.html/feed</wfw:commentRss>
			<slash:comments>52</slash:comments>
		
		
			</item>
		<item>
		<title>千万别用MongoDB？真的吗？！</title>
		<link>https://coolshell.cn/articles/5826.html</link>
					<comments>https://coolshell.cn/articles/5826.html#comments</comments>
		
		<dc:creator><![CDATA[陈皓]]></dc:creator>
		<pubDate>Thu, 10 Nov 2011 00:28:26 +0000</pubDate>
				<category><![CDATA[数据库]]></category>
		<category><![CDATA[轶事趣闻]]></category>
		<category><![CDATA[10gen]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[MongoDB]]></category>
		<guid isPermaLink="false">http://coolshell.cn/?p=5826</guid>

					<description><![CDATA[<p>某人发了一篇Don&#8217;t use MongoDB的血泪控诉，我把原文翻译如下，你可以看看。不过，我想我们还要去看看10gen CTO的对此事的回复，我...</p>
<p class="read-more"><a class="btn btn-default" href="https://coolshell.cn/articles/5826.html"> Read More<span class="screen-reader-text">  Read More</span></a></p>
The post <a href="https://coolshell.cn/articles/5826.html">千万别用MongoDB？真的吗？！</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></description>
										<content:encoded><![CDATA[<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415450859608158"
     crossorigin="anonymous"></script>某人发了一篇<a href="http://pastebin.com/raw.php?i=FD3xe6Jt" target="_blank">Don&#8217;t use MongoDB</a>的血泪控诉，我把原文翻译如下，你可以看看。不过，我想我们还要去看看10gen <a href="http://news.ycombinator.com/item?id=3202081" target="_blank">CTO的对此事的回复</a>，我们还要去在<a href="http://www.reddit.com/r/programming/comments/m2b2b/dont_use_mongodb/" target="_blank">Reddit上</a>看看大家的说法，10gen <a href="http://news.ycombinator.com/item?id=3202081" target="_blank">CTO的对此事的回复</a>后面也有一堆人在讨论这个事，还有一些程序员开始去读MongoDB的源码了，呵呵。看样子，说MongoDB的这些事并不是真的。</p>
<p>10gen CTO 对此事的并不完全知道，其在回复，对些文中的每一条都做了回复。我把其回复的大体意思也放在原文中。不过，很有意思的是那些程序员的讨论。建议大家看看。</p>
<h3>正文</h3>
<p>因为各种政治原因，我这段时间没有说什么，但是现在我觉得因为要对社会负责，所以我要阻止大家不要把你们的业务放在MongoDB上。</p>
<p>我的团队在一个有巨大用户量（一个有千万用户级的大型的公司）系统上使用的MongoDB，这个系统上让MongoDB有非常大的负载。早期，我们以为使用MongoDB会像10gen公司（MongoDB背后的公司）宣扬其在长期性能扩展有很多好处。但是，我们错了，而这个rant(长篇抱怨)就是为了让你不要相信那些所谓的成功经验而和我们一样犯了大错。如果有人能避免你上当，那么就得我写这么多。希望能警醒更多的人。</p>
<p>注意，对于和10gen打交道的经历来说，他们给予了我们充分了热情和帮助，而且非常地好。但是这并不能成为我不告诉大家他们的产品失败的理由。</p>
<p><span id="more-5826"></span></p>
<h4>为什么这么说？</h4>
<p>数据库应该是正确的，或是仅可能的正确，因为数据库的错误会比其它使用更大。不仅仅是因为其对运行，性能，开销，和其价值影响巨大，还因为其连带的东西。匆忙去去移植TB级的数据相比起去修改代码中的一个逻辑错误来说是一个很巨大的工作。而在系统出问题后需要恢复TB级的数据，而你即被限制住了，你会有一种绝望的感觉。</p>
<p>数据库是一个很复杂的系统，对于开发者来说就像一个黑盒一样。你需要对你所采用的数据库持绝对信任的态度，信任它会做正确的事，并尽会保持 一致笥和可用性。</p>
<p>为什么MongoDB会流行？</p>
<p>说句公道话，我们必需承认MongoDB是流行的，因为下面这些原因让其流行变得很合理：</p>
<ul>
<li>它非常容易地运行</li>
<li>非常自由的Schema模型，而且可以很容易地和JSON类的数据结果映射起来，这对于程序员来于有很大的感染力（它完全符合程序员的逻辑思维），而且，程序员总是在项目可以做技术选型的人。</li>
<li>成熟和分健壮，有记录，被真实的Use Case测试过，等等。对于那些喜欢选择成熟的技术的系统管理员和运营专业来说，这是一个很典型的选择。</li>
<li>它单系统，低读并发的性能测试非常令人惊讶，而对于那些没有经验的评估者来说，这基本上来说是最重要的。</li>
</ul>
<p>现在，你可能正在开发一个随便玩一玩的网站，或是一个原型，或是那种只考虑开发速度不考虑别的的项目。老实说，对于这种项止，无所谓你用什么样的技术，只要搞定工作就行了。</p>
<p>但是，如果你想要在MongoDB上搞一个大规模的系统，在上面运行真实的业务，那么，请不要用MongoDB。</p>
<h4>为什么不？</h4>
<p>1）MongoDB为了赢得Benchmark测试而默认使用了不安全的写方式</p>
<p>如果你不调用getLastError()，MongoDB就不会在确认数据库写操作完成就返回了，这会引入至少两种问题：</p>
<ul>
<li>在并发的环境下（连接池，等），在一个读操作“完成”后的连续地读操作会出错，MongoDB没有“栅栏条件锁”来知道什么时候完成写。</li>
<li>未知个数的保存操作会被丢弃，因为保存操作的队列会在不同的地方。比如TCP缓存等。当你和数据库连接因为一些意味情况断开的时候，这些东西就被丢弃了。</li>
</ul>
<blockquote>
<div>10gen CTO 回复： 这和Benchmark没有任何关系，并说这个就是API的设计，其交给用户自己去选择，因为写的方式也有很多种。</div>
</blockquote>
<p>2）MongoDB会以令人震惊的方式丢失数据</p>
<p>下面是一个我们所经历过的它丢数据的列表：</p>
<ul>
<li>数据就是丢了，原因未知</li>
<li>从损坏的数据库中恢复数据不成功，如事务日志。</li>
<li>主从结点间的数据复制有缺口，导致从结点丢失主结点有的数据。是的，没有CheckSum，并且是的，你还会看到数据复制过去了。</li>
<li>数据复制有时会停了，没有错误。你可以监控你的复制状态。</li>
</ul>
<blockquote>
<div>10gen CTO 逐一回复：1）从来没有一个数据丢失的BUG我们没有马上fix的事情。你能告诉我你报给我们的问题号吗？我们至少要明的是怎么一回事。如果是我们的问题，我们会马上fix的。2）从损坏了的数据库中不能完全恢复数据 ，这不挺正常的吗？但是如果有主从服务器互为备份应该会好一些。3）请告诉我你的问题号，我们从来没有接到过这样的错误报告。如果有，的确很严重。4）如果是说错误条件发生的时候没有通知，这有可能。另外，你可以监控数据复制的写操作，你可以使用w=2 为getLastError的参数。</div>
</blockquote>
<p>3）MongoDB 需要全局写锁来请求写操作</p>
<p>在写操作频繁的时候，这等同于杀了你。如果你运行一个blog，你也许不会关心这个事，因为你的读写操作不高。</p>
<blockquote><p>10gen CTO 回复：读写锁永远都是问题，但是2.0会好很多，2.2会解决得更好一些。</p></blockquote>
<p>4）MongoDB 的Sharding(分区) 在高负载下会停止工作</p>
<p>在高负载下加一个shard是一场恶梦。Mongo要么会移动其数据块太快而导致DOS攻击产生很多流量占用带宽，要么就完全地拒绝更多的数据块。这会使一个高流量的网站承受着沉重地写操作。</p>
<blockquote><p>10gen CTO 回复：如果系统已经超过了其负载，那么移动数据当然会变得很难。我每一次的演讲都说得很清楚，不要在系统性能不行的时候才去加shard，这不行的。</p></blockquote>
<p>5）Mongo 不可靠</p>
<p>Mongod/配置服务器/mongos的架构确定合理且聪明。不幸的是，mongos完全就是垃圾。在有负载的情况下，它时不时就都会崩溃，有时几个小时，有时几天。进程重启监控有时也不管用，因为他会抛出一些断言会伪造出一个关键线程，其导致进程还在运行。Double Fail。</p>
<p>最坏的是，唯一可行的方式是在一堆mongos实例前放一个HaProxy(一种负载均衡器)，运行一个作业其缓慢地轮着访问这些mongos实例，并定期kill掉他们，以变可以重新启动新的实例。我没有在开玩笑。</p>
<blockquote><p>10gen CTO 回复：不可能有这种事，你能不能告诉我更多的细节？</p></blockquote>
<p>6）MongoDB有一次甚至删除了整个数据库</p>
<p>MongoDB 1.6，在数据同步配置中，有时会配置了一个错误的结点（经常是一个空结点）是一个最新的数据结点。于是其它同步数据的结果上的<strong>数据就这样被干掉了</strong>（我说的是700GB的好数据），因为其把这个空结点的数据同步回有数据的结点上。数据库永远永远都不应该干这个。如果出现这种问题，数据库应该抛出一个错误而让DBA来选择合理的操作，或是强制使用正确的配置。而不应该删除所有的数据（那天太糟糕了）。</p>
<p>他们在1.8中修复了这个问题，偶滴神啊。</p>
<blockquote><p>10gen CTO 回复：找不到这样的事，也找不到相应提交的代码，你能多给点信息吗？</p></blockquote>
<p>7）发布了一些不应该发布东西</p>
<p>众所周知，在稳定版里能找到一些尴尬的bug其会导致数据问题——而我们总是在出了问题后他们才告诉我们这些问题，这是因为我们购买了10gen他们那超级诈骗的白金技术支持。他们回应是，发给我们一个hot patch，他们内部叫RC的玩意，然后让这个hot patch运行在我们的数据上。</p>
<blockquote><p>10gen CTO 回复：关于白金的技术支持，我们所接手的所有问题都会公开，fix也会公开。没有特定的情景，这种事很难讨论。我们会根据不同的情况作出不同的反应。我们希望我们的用户的问题能尽快得到解决。</p></blockquote>
<p>8）复制器在繁忙的服务器上黯然失色</p>
<p>复制器经常性的向Master发起DOS攻击，或是复制非常慢，花了巨长无比的时间，而oplog几乎被耗尽（就算是50GB的oplog）。</p>
<p>我们有一个繁忙的，大的数据集我们不会复制他因为它是动态的。那是令人痛苦的一个月，或是我们需要在选择不同的数据库系统前交叉双指（注：好运的手势）</p>
<blockquote><p>10gen CTO 回复：这看起来像上服务器负载过重了。我前面提到过了。</p></blockquote>
<p><strong>但是最糟糕的问题是：</strong></p>
<p>你可能会说，我这些问题都是过去式了；他们修复了所有这些问题或是他们会在下一版本中修复这些问题；X问题可以用Y实践来减轻。等等，等等。</p>
<p>不幸的是，你说这些东西一点用也没有。</p>
<p>真正的问题是，这么多的问题都是首要的问题。 数据库开发者要能hold住比一般程序员更高的标准。也就是说，你的优先级应该像下面这个样子：</p>
<ol>
<li>别搞丢数据，对数据要有完全的把握</li>
<li>通过实践保证可用性</li>
<li>多结点的性能扩展性</li>
<li>最小延迟应该保持在99%和95%之间</li>
<li>每个资源的每秒请求数</li>
</ol>
<p>10gen的顺序好像是 #5  为每一，其它项随便，#1 并不在前3位。</p>
<blockquote><p>10gen CTO 回复：这明显不是真的。看一看我们提交的代码，看一看我们的fix。 我们从来不会在release版中隐藏一个bug。如果我们非常在乎性能的benchmark的话，我们会花精力解决那些锁的问题，这样一来，多线程并发会更快一些。</p>
<p>MongoDB是一个新生的东西，还有很多东西需要打磨。如果你想来认识一下我们，我们欢迎你来认识一下我们。</p></blockquote>
<p>这些失败，还有那所暗示的公司的优先级，指出了一个最基本的企业文化的问题，其会让问题出现在任一发布版中：因为他们缺乏尊守必要的数据库系统的设计律条。</p>
<p>请慎重考虑这些警告。</p>
<p>（全文完）<!--



<p align="center"><a href= target=_blank><img decoding="async" src=""></a></p>





<p align="center"><img decoding="async" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.weixin.jpg"> <img decoding="async" loading="lazy" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.mini_.jpg" width="300" height="300"> <br />关注CoolShell微信公众账号和微信小程序</p>

 

--></p>
<div style="margin-top: 15px; font-size: 16px;color: #cc0000;">
<p align="center"><strong>（转载本站文章请注明作者和出处 <a href="https://coolshell.cn/">酷 壳 &#8211; CoolShell</a> ，请勿用于任何商业用途）</strong></p>
</div>

<div class="wp_rp_wrap  wp_rp_vertical_m" ><div class="wp_rp_content"><h3 class="related_post_title">相关文章</h3><ul class="related_post wp_rp"><li ><a href="https://coolshell.cn/articles/17607.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2017/01/MongoDB-150x150.jpg" alt="从 MongoDB “赎金事件” 看安全问题" width="150" height="150" /></a><a href="https://coolshell.cn/articles/17607.html" class="wp_rp_title">从 MongoDB “赎金事件” 看安全问题</a></li><li ><a href="https://coolshell.cn/articles/7270.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/05/overview2-1-150x150.png" alt="NoSQL 数据建模技术" width="150" height="150" /></a><a href="https://coolshell.cn/articles/7270.html" class="wp_rp_title">NoSQL 数据建模技术</a></li><li ><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/7.jpg" alt="开源中最好的Web开发的资源" width="150" height="150" /></a><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_title">开源中最好的Web开发的资源</a></li><li ><a href="https://coolshell.cn/articles/3311.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/23.jpg" alt="几篇技术文章" width="150" height="150" /></a><a href="https://coolshell.cn/articles/3311.html" class="wp_rp_title">几篇技术文章</a></li><li ><a href="https://coolshell.cn/articles/1889.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2009/12/sql.where_.clause-150x150.jpg" alt="SQL的Where语句" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1889.html" class="wp_rp_title">SQL的Where语句</a></li><li ><a href="https://coolshell.cn/articles/1846.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2009/11/unoptimized_explain-150x150.jpg" alt="MySQL性能优化的最佳20+条经验" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1846.html" class="wp_rp_title">MySQL性能优化的最佳20+条经验</a></li></ul></div></div>The post <a href="https://coolshell.cn/articles/5826.html">千万别用MongoDB？真的吗？！</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></content:encoded>
					
					<wfw:commentRss>https://coolshell.cn/articles/5826.html/feed</wfw:commentRss>
			<slash:comments>32</slash:comments>
		
		
			</item>
		<item>
		<title>开源中最好的Web开发的资源</title>
		<link>https://coolshell.cn/articles/4795.html</link>
					<comments>https://coolshell.cn/articles/4795.html#comments</comments>
		
		<dc:creator><![CDATA[陈皓]]></dc:creator>
		<pubDate>Wed, 08 Jun 2011 00:28:52 +0000</pubDate>
				<category><![CDATA[Web开发]]></category>
		<category><![CDATA[杂项资源]]></category>
		<category><![CDATA[CSS3]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<guid isPermaLink="false">http://coolshell.cn/?p=4795</guid>

					<description><![CDATA[<p>文章来源：Best “must know” open sources to build the new Web。个人感觉这个收集贴收集成相当的全。 学习HTML...</p>
<p class="read-more"><a class="btn btn-default" href="https://coolshell.cn/articles/4795.html"> Read More<span class="screen-reader-text">  Read More</span></a></p>
The post <a href="https://coolshell.cn/articles/4795.html">开源中最好的Web开发的资源</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></description>
										<content:encoded><![CDATA[<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415450859608158"
     crossorigin="anonymous"></script>文章来源：<a title="Best “must know” open sources to build the new Web" href="http://www.b2bweb.fr/molokoloco/best-must-know-ressources-for-building-the-new-web-%E2%98%85/" target="_blank">Best “must know” open sources to build the new Web</a>。个人感觉这个收集贴收集成相当的全。</p>
<h4>学习HTML 5编程和设计</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="wallOfWonder" src="http://www.b2bweb.fr/wp-content/uploads/wallOfWonder.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://www.html5rocks.com/" target="_blank"><strong>HTML5 Rocks</strong></a> : Major Feature Groups  的学习 HTML5 的资源 (HTML5 演示, 教程 ). <a href="http://code.google.com/p/html5rocks/" target="_blank">源码</a></li>
<li>很不错的 <a href="https://mozillademos.org/demos/dashboard/demo.html" target="_blank"><strong>HTML5 Dashboard</strong></a> &#8211; Mozilla，效果很炫。</li>
<li><a href="http://developers.whatwg.org/" target="_blank"><strong>WhatWG Developers</strong></a>, 一个清楚的 HTML5 技术规格说明书。</li>
<li>★ <a href="http://stackoverflow.com/" target="_blank"><strong>StackOverflow</strong></a> : 大名鼎鼎的技术问答式论坛。</li>
<li>★ <a href="http://addyosmani.com/blog/" target="_blank"><strong>Addyosmani</strong></a>, jQuery 和 JavaScript 文章教程</li>
<li><a href="http://www.sohtanaka.com/web-design-tutorials/" target="_blank"><strong>Sohtanaka</strong></a>, jQuery 和 JavaScript 文章和教程</li>
<li>★ <a href="http://net.tutsplus.com/category/tutorials/" target="_blank"><strong>Nettuts+</strong></a> 是一个面对Web开发人员和设计人员的网站，提供各种技术教程和文章，覆盖 HTML, CSS, Javascript, CMS’s, PHP 和 Ruby on Rails.</li>
<li><a href="http://tympanus.net/codrops/" target="_blank"><strong>Codrops</strong></a>, 教程和 web 资源</li>
<li><a href="http://www.webappers.com/" target="_blank"><strong>WebAppers</strong></a>, 最好的开源资源</li>
<li><a href="http://tutorialzine.com/" target="_blank"><strong>Tutorialzine</strong></a> – PHP MySQL jQuery CSS 教程, 资源和赠品</li>
<li><strong><a href="https://developer.mozilla.org/en/JavaScript/Guide" target="_blank">Mozilla JavaScript guide</a></strong></li>
<li> <a href="http://code.google.com/p/molokoloco-coding-project/" target="_blank"><strong>codes snippets</strong></a>, 作者自己收集的一些代码片段</li>
</ul>
<p><span id="more-4795"></span></p>
<h4>服务器端的软件</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="nodeJs" src="http://www.b2bweb.fr/wp-content/uploads/nodeJs.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://nodejs.org/" target="_blank"><strong>Node.js</strong></a> 是服务器端的 JavaScript 环境，其使用了异步事件驱动模式。其让Node.js在很多互联网应用体系结构下获得非常不错的性能。 <a href="https://github.com/joyent/node/" target="_blank">源码</a> 和 <a href="http://jsapp.us/" target="_blank">实时演示</a>。</li>
<li><a href="http://www.phantomjs.org/" target="_blank"><strong>PhantomJS</strong></a> 也是一个服务器端的 JavaScript API的WebKit。其支持各种Web标准： DOM 处理, CSS 选择器, JSON, Canvas, 和 SVG</li>
<li><strong><a href="http://www.lighttpd.net/" target="_blank">Lighttpd</a></strong> 一个轻量级的开源Web服务器。新闻，文档，benchmarks, bugs, 和 download. Lighttpd 支撑了几个非常著名的 Web 2.0 网站，如：YouTube, wikipedia 和 meebo.</li>
<li><strong><a href="http://nginx.net/" target="_blank">NGinx</a></strong>, 性能巨高无比的轻量级的Web服务器。比Apache高多了。花了6年的时间，终于走到了1.0版。</li>
<li><strong><a href="http://httpd.apache.org/" target="_blank">Apache HTTP Server</a></strong> 是一个很流行的并支持多个流行的操作系统的Web服务器。</li>
<li>★ <strong><a href="http://nodejs.org/" target="_blank"></a><a href="http://www.php.net/" target="_blank">PHP</a></strong> 可能是最流行的服务器端的Web脚本动态处理语言。</li>
<li>当然，还有 <strong><a href="http://www.ruby-lang.org/fr/" target="_blank">Ruby</a></strong>, <strong><a href="http://www.python.org/" target="_blank">Python</a></strong>, <strong><a href="http://www.erlang.org/" target="_blank">Erlang</a></strong>, <strong><a href="http://www.perl.org/" target="_blank">Perl</a></strong>, <strong><a href="http://www.java.com/fr/" target="_blank">Java</a></strong>, <strong><a href="http://www.microsoft.com/net/" target="_blank">.NET</a></strong>, <strong><a href="http://www.android.com/" target="_blank">Android</a></strong>, <strong><a href="http://cpp.developpez.com/" target="_blank">C++</a></strong>, <strong><a href="http://golang.org/" target="_blank">Go</a></strong>,<a href="https://github.com/pmcelhaney/Mustache.cfc"></a><strong><a href="http://fantom.org/" target="_blank"> Fantom</a></strong>,<strong><a href="http://jashkenas.github.com/coffee-script/" target="_blank">CoffeeScript</a></strong>, <strong><a href="http://www.digitalmars.com/" target="_blank">D</a></strong>, …</li>
</ul>
<h4>PHP 框架和工具</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="drupal" src="http://www.b2bweb.fr/wp-content/uploads/drupal.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://wordpress.org/download/" target="_blank"><strong>WordPress</strong></a> 是一个基于博客系统的开源软件。参看《<a title="WordPress是怎么赢的？" href="https://coolshell.cn/articles/3716.html" target="_blank">WordPress是怎么赢的？</a>》</li>
<li><strong><a href="http://drupal.org/" target="_blank">Drupal</a></strong> 是一个内容管理系统 (CMS).</li>
<li><a href="http://www.centurion-project.org/" target="_blank"><strong>Centurion</strong></a> 是一个新出现的开源 CMS ，一个灵然的 PHP5 Content Management Framework. 使用 Zend Framework, 其组件坚持通用，简单，清楚和可重用的设计原则。</li>
<li><strong><a href="http://www.phpbb.com/" target="_blank">phpBB</a></strong> 一个开源的论坛（国内的Discuz！更多）</li>
<li><strong>★ <a href="http://simplepie.org/" target="_blank">SimplePie</a></strong> : 超快的，易用的,  RSS  和 Atom feed PHP解析。</li>
<li><strong>★ <a href="http://phpthumb.gxdlabs.com/" target="_blank">PHPthumb</a></strong>, PHP 图片处理库</li>
<li><strong>★ <a href="http://phpmailer.worxware.com/" target="_blank">PHPMailer</a></strong> 强大的全功能的PHP邮件库</li>
<li><strong><a href="http://code.google.com/p/pubsubhubbub/" target="_blank">PubSubHubbub</a></strong>协议，一个简单，开放， server-to-server 的 pubsub (publish/subscribe) 协议——Atom and RSS的扩展。</li>
<li>更多的请参看 &#8211; <a title="20 你应该知道的PHP库" href="https://coolshell.cn/articles/200.html" target="_blank">20个你应该知道PHP库</a> 和 <a title="9个强大免费的PHP库" href="https://coolshell.cn/articles/455.html" target="_blank">9个强大免费的PHP库</a></li>
</ul>
<h4>数据库</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="sqldesigner" src="http://www.b2bweb.fr/wp-content/uploads/sqldesigner.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://couchdb.apache.org/" target="_blank"><strong>Apache CouchDB</strong></a> 是一个面向文档的数据库管理系统。它提供以JSON 作为数据格式的REST 接口来对其进行操作，并可以通过视图来操纵文档的组织和呈现。.<a href="https://github.com/apache/couchdb" target="_blank">源码</a>.</li>
<li><a href="http://code.google.com/p/monoql/" target="_blank"><strong>MonoQL</strong></a> 是一个采用PHP+ExtJS开发的MySQL数据库管理工具。界面极像一个桌面应用程序，支持大部分常用的功能包括：表格设计，数据浏览/编辑，数据导入/导出和高级查询等。</li>
<li><strong> </strong><a href="http://mariadb.org/"><strong>MariaDB</strong></a> 是<a title="MySQL" href="http://www.mysql.com/" target="_blank">MySQL</a>的一个分支，由MySQL 创始人Monty Widenius 所开发。GPL，用来对抗Oracle所有的MySQL的license的不测。自Oracle收购SUN以来，整个社区对于MySQL前途的担忧就没有停止过。</li>
<li>★ <a href="http://www.sqlite.org/" target="_blank"><strong>SQLite</strong></a> 不像常见的客户端/服务器结构范例，SQLite引擎不是个程序与之通信的独立进程，而是连接到程序中成为它的一个主要部分。所以主要的通信协议是在编程语言内的直接API调用。这在消耗总量、延迟时间和整体简单性上有积极的作用。整个数据库（定义、表、索引和数据本身）都在宿主主机上存储在一个单一的文件中。它的简单的设计是通过在开始一个事务的时候锁定整个数据文件而完成的。库实现了多数的SQL-92标准，包括事务，就是代表原子性、一致性、隔离性和持久性的（ACID），触发器和多数的复杂查询。不进行类型检查。你可以把字符串插入到整数列中。某些用户发现这是使数据库更加有用的创新，特别是与无类型的脚本语言一起使用的时候。其他用户认为这是主要的缺点。</li>
<li><strong><a href="http://ondras.zarovi.cz/sql/demo/" target="_blank">SQL 在线设计编辑器</a></strong>，这一节的那个图片就是这个在线编辑器的样子了。一个画数据库图表的在线工具。很强大。</li>
</ul>
<h4>API 和 在线数据</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="yql" src="http://www.b2bweb.fr/wp-content/uploads/yql.png" alt="" width="600" height="238" /></p>
<ul>
<li><a href="http://www.programmableweb.com/apis/directory" target="_blank"><strong>ProgrammableWeb</strong></a>, 最流行的Web Services 和 API 目录大全。</li>
<li><strong><a href="http://code.google.com/intl/fr/apis/gdata/docs/directory.html" target="_blank">Google Data Protocol</a></strong> 一组Google服务的数据服务API。</li>
<li><a href="http://developer.yahoo.com/everything.html" target="_blank"><strong>Yahoo! Developer Network</strong></a> – APIs 和 Tools</li>
<li><a href="http://pipes.yahoo.com/" target="_blank"><strong>Yahoo! Pipes</strong></a> 可视化在线编程工具，它是一个用于过滤、转换和聚合网页内容的服务。</li>
<li>★ The <a href="http://developer.yahoo.com/yql/console/" target="_blank"><strong>Yahoo! Query Language</strong></a> 一个很像 SQL的网页查询工具。</li>
</ul>
<h4>在线代码和媒体编辑器</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="jsfiddle" src="http://www.b2bweb.fr/wp-content/uploads/jsfiddle.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://www.coderun.com/" target="_blank"><strong>CodeRun Studio</strong></a>一个基于JavaScript语言开发的跨平台的集成开发环境，它立足于云计算的设计思路，方便开发者在浏览器端便可以轻松开发、调试和部署网络应用程序。（参看《<a rel="bookmark" href="https://coolshell.cn/articles/1883.html" target="_blank">Coderun.com 在线开发IDE</a>》）</li>
<li><a href="https://github.com/ajaxorg/cloud9" target="_blank"><strong>Cloud9 IDE</strong></a> – 一个基于Node.JS构建的JavaScript程序开发Web IDE。它拥有一个非常快的文本编辑器支持为JS, HTML, CSS和这几种的混合代码进行着色显示。</li>
<li>★ <a href="http://jsfiddle.net/" target="_blank"><strong>jsFiddle</strong></a> – Javascript的在线运行展示框架，这个工具可以有效的帮助web前端开发人员来有效分享和演示前端效果，其简单而强大 (JavaScript, MooTools, jQuery, Prototype, YUI, Glow and Dojo, HTML, CSS)</li>
<li><strong><a href="http://www.akshell.com/" target="_blank">Akshell</a>，</strong>一种云服务，它使用服务端的JavaScript和在线的IDE帮助开发者进行快速应用程序开发。 它还提供云托管，所以部署是即时的。</li>
<li><a href="http://braincast.nl/samples/jsoneditor/" target="_blank"><strong>JSONeditor</strong></a>, 一个好用的JSON 编辑器</li>
<li>★ <a href="http://tinymce.moxiecode.com/wiki.php/TinyMCE" target="_blank"><strong>TinyMCE</strong></a> 一个轻量级的基于浏览器的所见即所得编辑器，支持目前流行的各种浏览器，由JavaScript写成。</li>
<li><a href="http://www.sencha.com/products/designer/" target="_blank"><strong>Ext Designer</strong></a> 是一个桌面应用工具，帮助你快速开发基于ExtJS 的用户界面。</li>
<li>★  <strong><a href="http://www.lucidchart.com/" target="_blank">LucidChart</a></strong>，一款基于最新的html5技术的在线图表绘制软件，功能强大，速度快捷，运行此软件需要支持html5的浏览器。</li>
<li><a href="http://balsamiq.com/products/mockups" target="_blank"><strong>Balsamiq Mockups</strong></a>, 产品设计师绘制线框图或产品原型界面的利器。</li>
<li><a href="http://colorschemedesigner.com/" target="_blank"><strong>Color Scheme Designer</strong></a> 3 &#8211; 一个免费的线上调色工具</li>
<li>★ <a href="http://pixlr.com/editor/" target="_blank"><strong>Pixlr</strong></a>, 是一个来自瑞典基于Flash的免费在线图片处理网站。除了操作介面和功能接近Photoshop，还是多语言版本，支持简体中文。（以前<a title="在线作图编辑服务" href="https://coolshell.cn/articles/3244.html" target="_blank">酷壳介绍过</a>）</li>
<li><a href="http://www.aviary.com/" target="_blank"><strong>Aviary</strong></a>, 是一个基于HTML5 的在线图片处理工具，可以很容易的对图片进行后期处理。 <a href="http://developers.aviary.com/" target="_blank">Aviary API</a></li>
<li><strong><a href="http://www.degraeve.com/favicon/" target="_blank">Favicon Generator</a>, </strong>线上favicon(16&#215;16)制作工具。</li>
</ul>
<h4>代码资源和版本控制</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="github" src="http://www.b2bweb.fr/wp-content/uploads/github.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="https://github.com/" target="_blank"><strong>GitHub</strong></a> 是一个用于使用Git版本控制系统的项目的基于互联网的存取服务。</li>
<li><a href="http://code.google.com/p/msysgit/" target="_blank"><strong>Git</strong></a> 是一个由Linus为了更好地管理linux内核开发而创立的分布式版本控制／软件配置管理软件。其巨快无比，高效，采用了分布式版本库的方式，不必服务器端软件支持，使源代码的发布和交流极其方便。</li>
<li><a href="http://code.google.com/" target="_blank"><strong>Google Code</strong></a> 谷歌公司官方的开发者网站，包含各种开发技术的API、开发工具、以及开发技术参考资料。</li>
<li><strong><a href="http://code.google.com/intl/zh-CN/apis/libraries/" target="_blank">Google Libraries API</a></strong> Google 将优秀的 JavaScript 框架部署在其 CDN 上，在我们的网站上使用 Google Libraries API 可以加速 JavaScript 框架的加载速度。</li>
<li><a href="http://snipplr.com/" target="_blank"><strong>Snipplr</strong></a> 一个开放的源代码技巧分享社区，号称Code 2.0。和一般的源码分享网站不同，它针对的并不是大型网站源码，而是一些编程的代码技巧。</li>
</ul>
<h4>JavaScript 桌面应用框架</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="jqueryUI" src="http://www.b2bweb.fr/wp-content/uploads/jqueryUI.jpg" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://jquery.com/" target="_blank"><strong>jQuery</strong></a> 是一个快速、简单的JavaScript library， 它简化了HTML 文件的traversing，事件处理、动画、Ajax 互动，从而方便了网页制作的快速发展。  <a href="https://github.com/jquery/jquery" target="_blank">源码</a>, <a href="http://api.jquery.com/" target="_blank">API</a>, <a href="http://api.jquery.com/browser/" target="_blank">API浏览</a>, <a href="http://interface.eyecon.ro/docs/animate" target="_blank">很不错的文档</a>.</li>
<li>★ 官方的 <a href="http://jqueryui.com/" target="_blank"><strong>jQuery User Interface (UI) library</strong></a> (演示和文档). <a href="https://github.com/jquery/jquery-ui%20" target="_blank">源码</a>,<a href="http://jqueryui.com/themeroller/" target="_blank">Themes Roller</a>, <a href="http://jqueryui.com/download" target="_blank">Download</a>.</li>
<li><a href="http://developer.yahoo.com/yui/2/" target="_blank"><strong>YUI 2</strong></a> — Yahoo! User Interface Library</li>
<li><a href="http://mootools.net/" target="_blank"><strong>Mootools</strong></a>, 一个超级轻量级的 web2.0 JavaScript framework</li>
<li><a href="http://www.prototypejs.org/" target="_blank"><strong>Prototype</strong></a> 提供面向对象的Javascript和AJAX</li>
<li><a href="http://dojotoolkit.org/" target="_blank"><strong>Dojo</strong></a> The Dojo Toolkit，一个强大的无法被打败的面向对象JavaScript框架。主要由三大模块组成：Core、Dijit、DojoX。Core提供Ajax,events,packaging,CSS-based querying,animations,JSON等相关操作API。Dijit是一个可更换皮肤，基于模板的WEB UI控件库。DojoX包括一些创新/新颖的代码和控件：DateGrid，charts，离线应用，跨浏览器矢量绘图等。</li>
<li>★ <a href="http://dev.sencha.com/deploy/ext-4.0.0/docs/" target="_blank"><strong>Ext JS 4</strong></a>, 业内最强大的 JavaScript framework。</li>
<li><a href="http://phpjs.org/functions/index" target="_blank"><strong>PHP.js</strong></a>, 一个开源的JavaScript 库，它尝试在JavaScript 中实现PHP 函数。在你的项目中导入<em>PHP.JS</em> 库，可以在静态页面使用你喜欢的PHP 函数。</li>
</ul>
<h4>JavaScript 移动和触摸框架</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="senchatouch" src="http://www.b2bweb.fr/wp-content/uploads/senchatouch.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://jquerymobile.com/" target="_blank"><strong>jQuery Mobile</strong></a> : 是 jQuery 在手机上和平板设备上的版本。jQuery Mobile 不仅会给主流移动平台带来jQuery核心库，而且会发布一个完整统一的jQuery移动UI框架。支持全球主流的移动平台。jQuery Mobile开发团队说：能开发这个项目，我们非常兴奋。移动Web太需要一个跨浏览器的框架，让开发人员开发出真正的移动Web网站。我们将尽全力去满足这样的需求。 <a href="https://github.com/jquery/jquery-mobile" target="_blank">Sources</a>.</li>
<li><a href="http://zeptojs.com/" target="_blank"><strong>Zepto.js</strong></a> Zepto.js 是支持移动WebKit浏览器的JavaScript框架，具有与jQuery兼容的语法。2-5k的库，通过不错的API处理绝大多数的基本工作。 <a href="https://github.com/madrobby/zepto" target="_blank">Sources</a>.</li>
<li><a href="http://microjs.com/" target="_blank"><strong>MicroJS</strong></a> : Microjs网站应用列出了很多轻量的Javascript类库和框架，它们都很小，大部分小于5kb。这样你不需要因为只需要一个功能就要加载一个JS的框架。</li>
<li>★ <a href="http://phonegap.com/" target="_blank"><strong>PhoneGap</strong></a> :是一款开源的手机应用开发平台，它仅仅只用HTML和JavaScript语言就可以制作出能在多个移动设备上运行的应用。 <a href="https://github.com/phonegap/phonegap" target="_blank">Sources</a>.</li>
<li>★ <a href="http://www.sencha.com/products/touch/" target="_blank"><strong>Sencha Touch</strong></a> Sencha Touch 是一个支持多种智能手机平台（iPhone, Android, 和BlackBerry）的 HTML5 框架。Sencha Touch可以让你的Web App看起来像Native App。美丽的用户界面组件和丰富的数据管理，全部基于最新的HTML5和CSS3的 WEB标准，全面兼容Android和Apple iOS设备。</li>
<li><a href="http://jqtouch.com/" target="_blank"><strong>JQtouch</strong></a>, 是一个jQuery 的插件，主要用于手机上的Webkit 浏览器上实现一些包括动画、列表导航、默认应用样式等各种常见UI效果的JavaScript 库。 <a href="http://github.com/senchalabs/jQTouch" target="_blank">Sources</a>.</li>
<li><a href="http://www.dhtmlx.com/touch/" target="_blank"><strong>DHTMLX Touch</strong></a> 针对移动和触摸设备的JavaScript 框架。DHTMLX Touch基于HTML5，创建移动web应用。它不只是一组UI 小工具，而是一个完整的框架，可以针对移动和触摸设备创建跨平台的web应用。它兼容主流的web浏览器，用DHTMLX Touch创建的应用，可以在iPad、iPhone、Android智能手机等上面运行流畅。</li>
</ul>
<h4>jQuery 插件</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="flexiGrid" src="http://www.b2bweb.fr/wp-content/uploads/flexiGrid.jpg" alt="" width="600" height="238" /></p>
<ul>
<li><a href="http://imakewebthings.github.com/jquery-waypoints/" target="_blank"><strong>Waypoints</strong></a> 是一个jQuery 用来实现捕获各种滚动事件的插件，例如实现无翻页的内容浏览，或者固定某个元素不让滚动等等。支持主流浏览器版本。</li>
<li><strong><a href="http://plugins.jquery.com/project/lazy" target="_blank">Lazy loader</a> </strong>插件可以实现图片的延迟加载，当网页比较长的时候，会先只加载用户视窗内的图片，视窗外的图片会等到你拖动滚动条至后面才加载，这样有效的避免了因图片过多而加载慢的弊端。</li>
<li><a href="https://github.com/gskinner/TweenJS" target="_blank"><strong>TweenJS</strong></a> : 一个简单和强大的 tweening / animation 的Javascript库。</li>
<li><a href="http://janne.aukia.com/easie/" target="_blank"> <strong>Easings</strong></a> 类Css3的jQuery 动画插件</li>
<li><a href="http://www.spritely.net/" target="_blank"><strong>Spritely</strong></a> 这个插件可以创建出如flash一样的动画效果，比如：在页面上有一只飞动的小鸟，一个动态滚动的背景等。</li>
<li><strong><a href="https://github.com/blueimp/jQuery-File-Upload/" target="_blank">File Upload</a>, </strong>jQuery 文件上传插件4.4.1</li>
<li><a href="http://www.agilecarousel.com/" target="_blank"><strong>Slideshow/Carousel</strong></a> 插件. <a href="https://github.com/edtalmadge/Agile-Carousel" target="_blank">Sources</a>.</li>
<li><a href="http://www.buildinternet.com/project/supersized/" target="_blank"><strong>Supersized</strong></a> – 全屏式的背景/幻灯片插件</li>
<li><a href="http://desandro.com/resources/jquery-masonry" target="_blank"><strong>Masonry</strong></a> i一款非常酷的自动排版插件，这款jQuery工具可以根据网格来自动排列水平和垂直元素，超越原来的css. <a href="https://github.com/desandro/masonry" target="_blank">Sources</a>.</li>
<li>jQuery 简单 <a href="http://layout.jquery-dev.net/demos.cfm" target="_blank"><strong>Layout</strong></a> 演示，管理各种边栏式，可改变大小式的布局。</li>
<li><a href="http://www.flexigrid.info/" target="_blank"><strong>Flexigrid</strong></a> – jQuery <a href="http://www.flexigrid.info/" target="_blank"><strong></strong></a>数据表插件</li>
<li><a href="http://isotope.metafizzy.co/" target="_blank"><strong>Isotope</strong></a>绝对是一个令人难以置信的<em>jQuery</em>插件，你可以用它来创建动态和智能布局。你可以隐藏和显示与过滤项目，重新排序和整理甚至更多。</li>
<li><a href="http://www.evanbyrne.com/article/super-gestures-jquery-plugin" target="_blank"><strong>Super Gestures</strong></a> jQuery 插件可以实现鼠标手势的功能。</li>
<li><a href="https://github.com/brandonaaron/jquery-mousewheel" target="_blank"><strong>MouseWheel</strong></a> 是由Brandon Aaron开发的<em>jQuery</em>插件，用于添加跨浏览器的鼠标滚轮支持。</li>
<li><a href="http://code.drewwilson.com/entry/autosuggest-jquery-plugin" target="_blank"><strong>AutoSuggest</strong></a> jQuery 插件可以让你添加一些自动完成的功能。</li>
<li><a href="http://craigsworks.com/projects/qtip/" target="_blank"><strong>qTip</strong></a> 一个漂亮的<em>jQuery</em> 的工具提示插件，这个插件功能相当强大。</li>
<li>jQuery <a href="http://www.highcharts.com/demo/" target="_blank"><strong>Charts and graphic</strong></a> 用来制作图表。</li>
<li>jQuery Tools– The <a href="http://flowplayer.org/tools/demos/" target="_blank"><strong>missing UI library</strong></a></li>
</ul>
<h4>其它 jQuery 资源</h4>
<ul>
<li><a href="http://www.smashingmagazine.com/2011/04/07/useful-javascript-and-jquery-tools-libraries-plugins" target="_blank">http://www.smashingmagazine.com/2011/04/07/useful-javascript-and-jquery-tools-libraries-plugins</a></li>
<li><a href="http://webdesigneraid.com/weekly-html5-news-and-inspirations-%E2%80%93-tutorials-tools-resources-and-freebies-v-2/" target="_blank">http://webdesigneraid.com/weekly-html5-news-and-inspirations-%E2%80%93-tutorials-tools-resources-and-freebies-v-2/</a></li>
<li><a href="http://www.designer-daily.com/15-useful-jquery-plugins-and-tutorials-5207" target="_blank">http://www.designer-daily.com/15-useful-jquery-plugins-and-tutorials-5207</a></li>
<li><a href="http://www.julien-verkest.fr/22/11/2007/240-plugins-jquery" target="_blank">http://www.julien-verkest.fr/22/11/2007/240-plugins-jquery</a></li>
<li><a href="http://www.hotscripts.com/blog/10-great-html5-experiments-apps/" target="_blank">http://www.hotscripts.com/blog/10-great-html5-experiments-apps/</a></li>
<li><a href="http://www.noupe.com/jquery/excellent-jquery-navigation-menu-tutorials.html" target="_blank">http://www.noupe.com/jquery/excellent-jquery-navigation-menu-tutorials.html</a></li>
<li><a href="http://www.noupe.com/php/20-useful-php-jquery-tutorials.html" target="_blank">http://www.noupe.com/php/20-useful-php-jquery-tutorials.html</a></li>
<li><a href="http://aext.net/2010/04/excellent-jquery-plugins-resources-for-data-presentation-and-grid-layout/" target="_blank">http://aext.net/2010/04/excellent-jquery-plugins-resources-for-data-presentation-and-grid-layout/</a></li>
<li><a href="http://webdesigneraid.com/html5-canvas-graphing-solutions-every-web-developers-must-know/" target="_blank">http://webdesigneraid.com/html5-canvas-graphing-solutions-every-web-developers-must-know/</a></li>
<li><a href="http://gestureworks.com/features/open-source-gestures/" target="_blank">http://gestureworks.com/features/open-source-gestures/</a></li>
<li><a href="http://edtechdev.wordpress.com/2011/01/14/some-exciting-new-html5javascript-projects/" target="_blank">http://edtechdev.wordpress.com/2011/01/14/some-exciting-new-html5javascript-projects/</a></li>
<li><a href="http://net.tutsplus.com/articles/web-roundups/30-developers-you-must-subscribe-to-as-a-javascript-junkie/" target="_blank">http://net.tutsplus.com/articles/web-roundups/30-developers-you-must-subscribe-to-as-a-javascript-junkie/</a></li>
</ul>
<h4>HTML5 视频播放器</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="leanBackPlayer" src="http://www.b2bweb.fr/wp-content/uploads/leanBackPlayer.jpg" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="https://github.com/webmademovies/popcorn-js" target="_blank"><strong>Popcorn.js</strong></a> 是一个HTML5 Video框架，它提供了易于使用的API来同步交互式内容，让操作HTML5 Video元素的属性，方法和事件变得简单易用。 (来自Mozilla)</li>
<li><a href="http://dev.mennerich.name/showroom/html5_video/" target="_blank"><strong>LeanBack Player</strong></a> HTML5视频播放器,没有依赖任何JavaScript框架。支持全屏播放，音量控制，在同一个页面中播放多个视频。 (来自Google)</li>
<li><a href="http://m.vid.ly/user/" target="_blank"><strong>Vid.ly</strong></a> 为你上传的视频提供转换功能，并且为转换后的视频创建一个短网址。通过Vid.ly，让你的视频可以在14种不同的浏览器和设备上播放，不需要再去考虑将要浏览视频的人使用什么设备了，以避免各各软件巨头之间的利益之争带来了不兼容，给用户带来了巨大的困扰，短网址让你可以通过Twitter、Facebook等方式方便分享视频。Vid.ly还可以通过html代码嵌入到其他网页中。Vid.ly免费帐户空间为1GB，免费帐户也没有播放或浏览限制。</li>
</ul>
<h4>JavaScript 音频处理与可视化效果</h4>
<p><img decoding="async" loading="lazy" title="soundmanager" src="http://www.b2bweb.fr/wp-content/uploads/soundmanager.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ 使用HTML5 和 Flash, <a href="http://www.schillmania.com/projects/soundmanager2/" target="_blank"><strong>SoundManager V2</strong></a> 只用单一API的提供了可靠，简单和强大的跨平台的音频处理。</li>
<li><a href="https://github.com/corbanbrook/dsp.js/" target="_blank"><strong>DSP</strong></a>, JavaScript的声音Digital Signal Processing</li>
<li>The Radiolab <a href="http://yoyodyne.cc/radiolab/" target="_blank"><strong>Hyper Audio Player</strong></a> v1, 带给你 WNYC Radiolab, SoundCloud 和 Mozilla Drumbeat</li>
<li><a href="http://jplayer.org/" target="_blank"><strong>jPlayer</strong></a>, 一个 jQuery HTML5 音频/ 视频库，功能齐全的API</li>
</ul>
<h4>JavaScript 图形 和 3D</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="processing" src="http://www.b2bweb.fr/wp-content/uploads/processing.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://processingjs.org/" target="_blank"><strong>Processing.js</strong></a>是一个开放的编程语言，在不使用Flash或Java小程序的前提下, 可以实现程序图像、动画和互动的应用。其使用Web标准，无需任何插件。</li>
<li>★ Javascript 3D 引擎: <a href="https://github.com/mrdoob/three.js" target="_blank"><strong>ThreeJS</strong></a> 由 Mr Doob 开发，一个轻量级的 3D 引擎，不需要了解细节，傻瓜都能使用。这个引擎可以使用&lt;canvas&gt;, &lt;svg&gt; 和 WebGL.</li>
<li><a href="http://www.iquilezles.org/apps/shadertoy/" target="_blank"><strong>Shader Toy</strong></a>, 一款使用WebGL的在线着色器编辑器(2D/3D). 基于在线的应用架构使您无需下载任何软件即可开始体验. Shader Toy包含大量实用着色器, 诸如光线追踪, 场景距离渲染, 球体, 隧道, 变形, 后期处理特效等.</li>
<li><a href="http://senchalabs.github.com/philogl/" target="_blank"><strong>PhiloGL</strong></a>, Sencha的PhiloGL是首个WebGL开发工具之一，提供了高水准的功能，来构建WebGL应用。Sencha创建了几个演示，来描述框架交互式3D虚拟化的能力，比如<a href="http://senchalabs.github.com/philogl/PhiloGL/examples/temperatureAnomalies/">3D view of global temperature changes</a>。</li>
<li><a href="http://benvanik.github.com/WebGL-Inspector/" target="_blank"><strong>WebGL Inspector</strong></a> 你就Firebug等Web调试工具一样，这个是 WebGL的调试工具。</li>
<li><a href="http://www.khronos.org/webgl/wiki_1_15/" target="_blank"><strong>WebGL frameworks</strong></a> 由 Khronos Group 收集的一个WebGL框架列表。</li>
<li><a href="http://easeljs.com/" target="_blank"><strong>EaselJS</strong></a>, 一个使用html5的canvas的 JavaScript 库. <a href="https://github.com/gskinner/EaselJS" target="_blank">Sources</a>.</li>
<li><a href="http://www.webresourcesdepot.com/free-javascript-game-frameworks-to-create-a-web-based-fun/" target="_blank"><strong>JavaScript Game Frameworks</strong></a> 免费的JS游戏框架列表。另，可参看 <a title="JS游戏引擎列表" href="https://coolshell.cn/articles/3516.html" target="_blank">JS游戏框架列表</a>。</li>
<li><a href="http://raphaeljs.com/" target="_blank"><strong>Raphaël</strong></a>是一个小型的JavaScript 库，用来简化在页面上显示向量图的工作。你可以用它在页面上绘制各种图表、并进行图片的剪切、旋转等操作。参看<a title="Javascript向量图Lib–Raphaël" href="https://coolshell.cn/articles/3107.html" target="_blank">Javascript向量图Lib–Raphaël</a></li>
<li><a href="http://keith-wood.name/svgRef.html" target="_blank"><strong>jQuery SVG</strong></a> 插件让你可以了 SVG canvas 进行交互。</li>
<li><a href="http://code.google.com/intl/fr/apis/chart/" target="_blank"><strong>Google chart tools</strong></a> &#8211;  参看本站的<a href="https://coolshell.cn/articles/582.html" target="_blank">使用Google API做统计图</a></li>
<li><a href="https://coolshell.cn/articles/582.html" target="_blank"></a><a href="http://arborjs.org/" target="_blank"><strong>Arbor.js</strong></a>, 是一个利用webworkers和jQuery创建的数据图形可视化JavaScript框架。它为图形组织和屏幕刷新处理提供了一个高效、力导向布局算法。</li>
</ul>
<h4>JavaScript 浏览器接口 (HTML5)</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="amplify" src="http://www.b2bweb.fr/wp-content/uploads/amplify.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://www.modernizr.com/" target="_blank"><strong>Modernizr</strong></a> – 是一个专为HTML5 和CSS3 开发的功能检测类库，可以根据浏览器对HTML5 和CSS3 的支持程度提供更加便捷的前端优化方案.<a href="https://github.com/Modernizr/Modernizr" target="_blank">Sources</a>. 一个有用的列表 <a href="https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-browser-Polyfills" target="_blank">cross-browser Polyfills</a></li>
<li><a href="http://code.google.com/p/html5shiv/" target="_blank"><strong>HTML5Shiv</strong></a> : 该项目的目的是为了让IE 能识别HTML5 的元素。</li>
<li><a href="https://github.com/remy/polyfills" target="_blank"><strong>Polyfills</strong></a> : 这个项目收集了一些代码片段其用Javascript支持不同的浏览器的特别功能，有些代码需要Flash。</li>
<li><a href="http://yepnopejs.com/" target="_blank"><strong>YepNopeJS</strong></a> : 一个异步的条件式的加载器。<a href="https://github.com/SlexAxton/yepnope.js" target="_blank">Sources</a>.</li>
<li>jQuery <a href="https://github.com/codler/jQuery-Css3-Finalize/" target="_blank"><strong>CSS3 Finalise</strong></a> : 是否厌倦了为每一个浏览器的CSS3属性加前缀？</li>
<li>★ <a href="http://amplifyjs.com/" target="_blank"><strong>Amplify.js</strong></a> :一套用于web应用数据管理和应用程序通讯的<strong> jQuery 组件库</strong>。提供简单易用的API接口。Amplify的目标是通过为各种数据源提供一个统一的程序接口简化各种格式数据的数据处理。Amplify的存储组件使用localStorage 和 sessionStorage标准处理客户端的存储信息，对一些老的浏览器支持可能有问题。Amplify&#8217;为jQuery的ajax方法request增加了一些额外的特性。 <a href="https://github.com/appendto/amplify" target="_blank">Sources</a>.</li>
<li><a href="https://github.com/balupton/history.js" target="_blank"><strong>History.js</strong></a> 优美地支持了HTML5 History/State APIs</li>
<li><a href="http://socket.io/" target="_blank"><strong>Socket.IO</strong></a> Web的socket编程。</li>
</ul>
<h4>JavaScript 工具</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="headJs" src="http://www.b2bweb.fr/wp-content/uploads/headJs.png" alt="" width="600" height="238" /></p>
<ul>
<li>★  {{<a href="http://mustache.github.com/" target="_blank"><strong>mustaches</strong></a>}} 小型的 JavaScript 模板引擎。</li>
<li><a href="http://jsonselect.org/" target="_blank"><strong>json:select()</strong></a>, CSS式的JSON选择器</li>
<li><a href="http://headjs.com/" target="_blank"><strong>HeadJS</strong></a>, 异步JavaScript装载。其最大特点就是不仅可以按顺序执行还可以并发装载载js。</li>
<li><a href="http://code.google.com/p/jsdoc-toolkit/" target="_blank"><strong>JsDoc Toolkit</strong></a>是一款辅助工具，你只需要根据约定在JavaScript 代码中添加相应的注释，它就可以根据这些注释来自动生成API文档。</li>
<li><a href="https://github.com/filamentgroup/Responsive-Images" target="_blank"><strong>Responsive image</strong></a>, 一个试验性的项目，用来处理<a href="http://www.alistapart.com/articles/responsive-web-design/">responsive layouts</a> 式的图片。</li>
<li><a href="http://marijnhaverbeke.nl/uglifyjs" target="_blank"><strong>UglifyJS</strong></a>是基于NodeJS的Javascript语法解析/压缩/格式化工具，它支持任何CommonJS模块系统的Javascript平台。</li>
<li><a href="http://www.dhteumeuleu.com/" target="_blank"><strong>Dhteumeuleu</strong></a>, 交互式的 DOM 脚本和DHTML 的开源演示。</li>
<li><a href="https://github.com/documentcloud/backbone/" target="_blank"><strong>Backbone</strong></a>是一个前端 JS 代码 MVC 框架，被著名的 37signals 用来构建他们的移动客户端。它不可取代 Jquery，不可取代现有的Template 库。而是和这些结合起来构建复杂的 web 前端交互应用。如果项目涉及大量的 javascript 代码，实现很多复杂的前端交互功能，首先你会想到把数据和展示分离。使用 Jquery 的 selector 和 callback 可以轻松做到这点。但是对于富客户端的WEB应用大量代码的结构化组织非常必要。Backbone 就提供了 javascript 代码的组织的功能。Backbone 主要包括 models, collections, views 和 events, controller 。</li>
</ul>
<h4>客户端和模拟器</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="firebug" src="http://www.b2bweb.fr/wp-content/uploads/firebug.png" alt="" width="600" height="238" /></p>
<ul>
<li><a href="http://browsershots.org/" target="_blank"><strong>BrowserShot</strong></a>, 检查浏览器的兼容性，跨浏览器平器的测试</li>
<li><strong><a href="http://tester.jonasjohn.de/" target="_blank">Test everything</a></strong>… 输入一个你想要测试的URL……</li>
<li><a href="http://tmobile.modeaondemand.com/htc/g1/" target="_blank"><strong>Android browser</strong></a> 模拟器</li>
<li><a href="http://iphonetester.com/" target="_blank"><strong>iPhone browser</strong></a> 模拟器</li>
<li><a href="http://www.opera.com/mobile/demo/" target="_blank"><strong>Opera browser</strong></a> 模拟器</li>
<li>★ <a href="http://getfirebug.com/whatisfirebug" target="_blank"><strong>Firebug</strong></a> 与 <strong><a href="http://www.mozilla.com/fr/firefox/" target="_blank">Firefox</a></strong> 集成，可以查看和调试你的Web页面。</li>
</ul>
<h3>CSS3 和 字库</h3>
<p><img decoding="async" loading="lazy" class="aligncenter" title="patternTap" src="http://www.b2bweb.fr/wp-content/uploads/patternTap.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://www.css3maker.com/" target="_blank"><strong>CSS3 Maker</strong></a> CCS3的生成器</li>
<li>容易地创建 <strong><a href="http://www.sencha.com/products/animator/" target="_blank">CSS3 animations</a>。</strong> Sencha Animator 是一个桌面应用可以为WebKit浏览器和触摸式移动设备创建 CSS3 animations 。</li>
<li><a href="http://csswarp.eleqtriq.com/" target="_blank"><strong>CSSwarp</strong></a> – CSS 文本扭曲生成器</li>
<li><a href="http://www.colorzilla.com/gradient-editor/" target="_blank"><strong>Gradient Editor</strong></a>, 一个强大的Photoshop式的CSS 渐变编译器。来自 ColorZilla</li>
<li>★ <a href="http://www.google.com/webfonts" target="_blank"><strong>Google Web Fonts</strong></a> 通过Google Web Fonts API 可以浏览所有的字体</li>
<li><a href="http://www.fontsquirrel.com/fontface/generator" target="_blank"><strong>@font-face Kit Generator</strong></a>, 为Web转换字体</li>
<li><a href="http://www.typetester.org/" target="_blank"><strong>Typetester</strong></a>, 比较字体。</li>
<li><a href="http://mediaqueri.es/" target="_blank"><strong>Media Queries</strong></a>. 一组 responsive web 设计。</li>
<li><a href="http://patterntap.com/" target="_blank"><strong>Pattern TAP</strong></a>, UI组件。</li>
</ul>
<h4>Website (FULL) 模板</h4>
<p><img decoding="async" loading="lazy" class="aligncenter" title="boilerplate" src="http://www.b2bweb.fr/wp-content/uploads/boilerplate1.png" alt="" width="600" height="238" /></p>
<ul>
<li>★ <a href="http://html5boilerplate.com/" target="_blank"><strong>HTML5 Boilerplate</strong></a> 是一个<a href="http://www.mhtml5.com/">HTML5 </a>/ CSS / js模板，是实现跨浏览器正常化、性能优化，稳定的可选功能如跨域Ajax和Flash的最佳实践。 项目的开发商称之为技巧集合，目的是满足您开发一个跨浏览器，并且面向未来的网站的需求。 <a href="https://github.com/paulirish/html5-boilerplate" target="_blank">Sources</a>.</li>
<li><a href="http://sickdesigner.com/resources/HTML5-starter-pack/" target="_blank"><strong>HTML5 starter pack</strong></a> 是一个干净的和有组织的目录结构，其可适合很多项目，还有一些很常用的文件，以及简单的Photoshop设计模板。</li>
<li>★ <a href="http://initializr.com/" target="_blank"><strong>Initializr</strong></a> 是一个HTML5 模板生成器，其可以帮你在15秒内创建一个HTML5的项目。</li>
<li><a href="http://tympanus.net/Tutorials/AnimatedPortfolioGallery/" target="_blank"><strong>Animated Portfolio Gallery</strong></a> （<a href="http://tympanus.net/codrops/2010/11/14/animated-portfolio-gallery/" target="_blank">教程</a>）</li>
<li> <a href="http://tutorialzine.com/2010/07/making-slick-mobileapp-website-jquery-css/" target="_blank"><strong>Slick MobileApp Website</strong></a> 如果通过 jQuery 和 CSS 制作一个手机应用的网站。</li>
<li> <a href="http://net.tutsplus.com/tutorials/javascript-ajax/how-to-build-an-rss-reader-with-jquery-mobile-2/" target="_blank"><strong>RSS Reader</strong></a> 如果通过 jQuery Mobile 创建一个RSS Reader</li>
<li>★ <a href="http://addyosmani.com/blog/building-spas-jquerys-best-friends/" target="_blank"><strong>Single Page Applications</strong></a> 使用jQuery的朋友们 (Backbone, Underscore, …)创建单一页面。</li>
<li><a href="http://code.google.com/p/gtv-resources/" target="_blank"><strong>Google TV Optimized Templates</strong></a>, 传统电视已经开始和网路融合，但现阶段产业仍然正在摸索之中，为此将来的网页亦会有结构上的改变。<a href="http://code.google.com/p/gtv-resources/">Google TV Optimized Templates</a>是一个用HTML/JavaScript制成的开源软体，一如其名是一个对Google TV作出了最佳化的的网页范本，其特色是以遥控器作为操作的前提，令使用者无需输入任何文字就可以进行控制。未来除了会有专用遥控器外，还会采用智能手机透过W-iFi控制Google TV的方法。Optimized Templates的界面中左方会展示分类，右方会显示该分类下的影片截图，影片播放、切换、全画面表示都可透过键盘上的方向键、Backspace或Enter等键完成，方便今后的网站开发人员借镜。HTML5 版的模板使用了 <a href="http://code.google.com/p/gtv-ui-lib" target="_blank">Google TV UI library</a>, jQuery  和 Closure 。</li>
</ul>
<p>（全文完）<!--



<p align="center"><a href= target=_blank><img decoding="async" src=""></a></p>





<p align="center"><img decoding="async" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.weixin.jpg"> <img decoding="async" loading="lazy" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.mini_.jpg" width="300" height="300"> <br />关注CoolShell微信公众账号和微信小程序</p>

 

--></p>
<div style="margin-top: 15px; font-size: 16px;color: #cc0000;">
<p align="center"><strong>（转载本站文章请注明作者和出处 <a href="https://coolshell.cn/">酷 壳 &#8211; CoolShell</a> ，请勿用于任何商业用途）</strong></p>
</div>

<div class="wp_rp_wrap  wp_rp_vertical_m" ><div class="wp_rp_content"><h3 class="related_post_title">相关文章</h3><ul class="related_post wp_rp"><li ><a href="https://coolshell.cn/articles/3684.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2011/02/1128-150x150.jpg" alt="Web开发人员速查卡" width="150" height="150" /></a><a href="https://coolshell.cn/articles/3684.html" class="wp_rp_title">Web开发人员速查卡</a></li><li ><a href="https://coolshell.cn/articles/9666.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2013/05/Render-Process-150x150.jpg" alt="浏览器的渲染原理简介" width="150" height="150" /></a><a href="https://coolshell.cn/articles/9666.html" class="wp_rp_title">浏览器的渲染原理简介</a></li><li ><a href="https://coolshell.cn/articles/5537.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2011/11/stackparts.com_-150x150.png" alt="一些文章资源和趣闻" width="150" height="150" /></a><a href="https://coolshell.cn/articles/5537.html" class="wp_rp_title">一些文章资源和趣闻</a></li><li ><a href="https://coolshell.cn/articles/5224.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2011/09/image008-150x150.jpg" alt="一些文章和各种资源" width="150" height="150" /></a><a href="https://coolshell.cn/articles/5224.html" class="wp_rp_title">一些文章和各种资源</a></li><li ><a href="https://coolshell.cn/articles/3903.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/14.jpg" alt="一些有意思的贴子和工具" width="150" height="150" /></a><a href="https://coolshell.cn/articles/3903.html" class="wp_rp_title">一些有意思的贴子和工具</a></li><li ><a href="https://coolshell.cn/articles/1949.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/16.jpg" alt="Web中的省略号" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1949.html" class="wp_rp_title">Web中的省略号</a></li></ul></div></div>The post <a href="https://coolshell.cn/articles/4795.html">开源中最好的Web开发的资源</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></content:encoded>
					
					<wfw:commentRss>https://coolshell.cn/articles/4795.html/feed</wfw:commentRss>
			<slash:comments>124</slash:comments>
		
		
			</item>
		<item>
		<title>几篇技术文章</title>
		<link>https://coolshell.cn/articles/3311.html</link>
					<comments>https://coolshell.cn/articles/3311.html#comments</comments>
		
		<dc:creator><![CDATA[陈皓]]></dc:creator>
		<pubDate>Thu, 25 Nov 2010 01:04:54 +0000</pubDate>
				<category><![CDATA[技术读物]]></category>
		<category><![CDATA[杂项资源]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[ebook]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Unix]]></category>
		<guid isPermaLink="false">http://coolshell.cn/?p=3311</guid>

					<description><![CDATA[<p>The Art of Unix http://www.faqs.org/docs/artu/ Perl for Impatient Developer http...</p>
<p class="read-more"><a class="btn btn-default" href="https://coolshell.cn/articles/3311.html"> Read More<span class="screen-reader-text">  Read More</span></a></p>
The post <a href="https://coolshell.cn/articles/3311.html">几篇技术文章</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></description>
										<content:encoded><![CDATA[<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415450859608158"
     crossorigin="anonymous"></script><strong>The Art of Unix</strong></p>
<p><a href="http://www.faqs.org/docs/artu/" target="_blank">http://www.faqs.org/docs/artu/</a></p>
<p><strong>Perl for Impatient Developer</strong></p>
<p><a href="http://blob.perl.org/books/impatient-perl/iperl.pdf" target="_blank">http://blob.perl.org/books/impatient-perl/iperl.pdf</a></p>
<p><strong>Game Development with Javascript</strong></p>
<p><a href="http://www.brighthub.com/hubfolio/matthew-casperson/blog/archive/2009/06/29/game-development-with-javascript-and-the-canvas-element.aspx" target="_blank">http://www.brighthub.com/hubfolio/matthew-casperson/blog/archive/2009/06/29/game-development-with-javascript-and-the-canvas-element.aspx</a></p>
<p><strong>Introduction to x64 Assembly</strong></p>
<p><a href="http://software.intel.com/en-us/articles/introduction-to-x64-assembly/" target="_blank">http://software.intel.com/en-us/articles/introduction-to-x64-assembly/</a></p>
<p><strong>Database Fundamental</strong></p>
<p><a href="https://www.ibm.com/developerworks/wikis/display/db2oncampus/FREE+ebook+-+Database+fundamentals">https://www.ibm.com/developerworks/wikis/display/db2oncampus/FREE+ebook+-+Database+fundamentals</a><!--



<p align="center"><a href= target=_blank><img decoding="async" src=""></a></p>





<p align="center"><img decoding="async" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.weixin.jpg"> <img decoding="async" loading="lazy" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.mini_.jpg" width="300" height="300"> <br />关注CoolShell微信公众账号和微信小程序</p>

 

--></p>
<div style="margin-top: 15px; font-size: 16px;color: #cc0000;">
<p align="center"><strong>（转载本站文章请注明作者和出处 <a href="https://coolshell.cn/">酷 壳 &#8211; CoolShell</a> ，请勿用于任何商业用途）</strong></p>
</div>

<div class="wp_rp_wrap  wp_rp_vertical_m" ><div class="wp_rp_content"><h3 class="related_post_title">相关文章</h3><ul class="related_post wp_rp"><li ><a href="https://coolshell.cn/articles/18360.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2018/05/300x262-150x150.jpg" alt="程序员练级攻略（2018)  与我的专栏" width="150" height="150" /></a><a href="https://coolshell.cn/articles/18360.html" class="wp_rp_title">程序员练级攻略（2018)  与我的专栏</a></li><li ><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/7.jpg" alt="开源中最好的Web开发的资源" width="150" height="150" /></a><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_title">开源中最好的Web开发的资源</a></li><li ><a href="https://coolshell.cn/articles/2053.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/20.jpg" alt="最为奇怪的程序语言的特性" width="150" height="150" /></a><a href="https://coolshell.cn/articles/2053.html" class="wp_rp_title">最为奇怪的程序语言的特性</a></li><li ><a href="https://coolshell.cn/articles/1850.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2009/11/programming_language-150x150.jpg" alt="Javascript程序员嘴最脏??" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1850.html" class="wp_rp_title">Javascript程序员嘴最脏??</a></li><li ><a href="https://coolshell.cn/articles/1532.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/24.jpg" alt="到处都是Unix的胎记" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1532.html" class="wp_rp_title">到处都是Unix的胎记</a></li><li ><a href="https://coolshell.cn/articles/1042.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2009/06/linux_tutorials-150x150.jpg" alt="Linux/Unix 新手和专家教程" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1042.html" class="wp_rp_title">Linux/Unix 新手和专家教程</a></li></ul></div></div>The post <a href="https://coolshell.cn/articles/3311.html">几篇技术文章</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></content:encoded>
					
					<wfw:commentRss>https://coolshell.cn/articles/3311.html/feed</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>SQL的Where语句</title>
		<link>https://coolshell.cn/articles/1889.html</link>
					<comments>https://coolshell.cn/articles/1889.html#comments</comments>
		
		<dc:creator><![CDATA[陈皓]]></dc:creator>
		<pubDate>Tue, 01 Dec 2009 05:48:25 +0000</pubDate>
				<category><![CDATA[编程语言]]></category>
		<category><![CDATA[轶事趣闻]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[SQL]]></category>
		<guid isPermaLink="false">http://coolshell.cn/?p=1889</guid>

					<description><![CDATA[<p>某DBA在查看自己的数库日志的时候，看到了数据库服务器上出现了很多很怪异的SQL的Where条件语句，是下面这个样子：（所有的where语句前都有了一个叫“1=...</p>
<p class="read-more"><a class="btn btn-default" href="https://coolshell.cn/articles/1889.html"> Read More<span class="screen-reader-text">  Read More</span></a></p>
The post <a href="https://coolshell.cn/articles/1889.html">SQL的Where语句</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></description>
										<content:encoded><![CDATA[<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415450859608158"
     crossorigin="anonymous"></script>某DBA在查看自己的数库日志的时候，看到了数据库服务器上出现了很多很怪异的SQL的Where条件语句，是下面这个样子：（所有的where语句前都有了一个叫“1=1”的子条件）呵呵。</p>
<p style="text-align: center;"><img decoding="async" loading="lazy" class="alignnone size-full wp-image-1890" title="SQL Where Clause" src="https://coolshell.cn/wp-content/uploads/2009/12/sql.where_.clause.jpg" alt="SQL Where Clause" width="460" height="631" srcset="https://coolshell.cn/wp-content/uploads/2009/12/sql.where_.clause.jpg 460w, https://coolshell.cn/wp-content/uploads/2009/12/sql.where_.clause-219x300.jpg 219w, https://coolshell.cn/wp-content/uploads/2009/12/sql.where_.clause-197x270.jpg 197w" sizes="(max-width: 460px) 100vw, 460px" /></p>
<p>要理解这个事情的原因其实并不难。只要你是一个编写数据库的程序员，你就会知道——动态生成where后的条件的“麻烦”，那就是条件的“分隔”-and或or。下面听我慢慢说来。</p>
<p><span id="more-1889"></span></p>
<p>我们知道，大多数的查询表单都需要用户输出一堆查询条件，然后我们的程序在后台要把这些子条件用and组合起来。于是，把and加在各个条件的中间就成为了一件“难事”，因为你的程序需要判断：</p>
<ul>
<li>如果没有条件的话，则不需要where</li>
<li>如果只有一个条件的话，不需要and.</li>
<li>如果有多个条件的话，
<ul>
<li>如果and是持续加在每个条件后面的话，那么就要判断是否是最后一个条件，因为最后一个不能加and.</li>
<li>同样，如果and是要加在每个条件前面的话，你就需要判断是否是第一个，如果是，那就不加。</li>
</ul>
</li>
</ul>
<p>真是TMD太烦了，所以，编程“大拿”引入了“1=1”条件语句。于是，编程的难度大幅度下降，你可以用单一的方式来处理这若干的查询子条件了。而1=1应该会被数据库引擎优化时给去掉了。</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
&lt;pre&gt;&lt;code&gt;$query = &quot;SELECT name FROM table WHERE 1=1 &quot;;

foreach($clauses as $key =&gt; $value){
    $query .= &quot; AND &quot;.escape($key).&quot;=&quot;.escape($value).&quot; &quot;;
}
&lt;/code&gt;&lt;/pre&gt;
</pre>
<p>呵呵，<strong>DBA怎么能够理解我们疯狂程序员的用心良苦啊</strong>。</p>
<p>另外，在这里说一下，这样的做法看似很愚蠢，但很有效，在PHP的世界中，也有人使用下面这样的做法——使用了PHP的implode函数。</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
&lt;pre&gt;&lt;code&gt;/**
 * @param string $base base of query, e.g. UPDATE table SET
 * @param string $logic logic for concatenating $assoc, e.g. AND
 * @param array $assoc associative array of `field`=&gt;&#039;value&#039; pairs to concatenate and append to $base
 * @param string $suffix additional clauses, e.g. LIMIT 0,30
 * @return string
 */
function construct_sql($base, $logic, $clauses, $suffix=&#039;&#039;)
{
    // initialise array to avoid warnings/notices on some PHP installations
    $queries = array();

    // create array of strings to be glued together by logic
    foreach($clauses as $key =&gt; $value)
        $queries[] = &quot;`&quot; . escape($key) . &quot;`=&#039;&quot; . escape($value) . &quot;&#039;&quot;;

    // add a space in case $base doesn&#039;t have a space at the end and glue clauses together
    $query .= &quot; &quot; . implode(&quot; $logic &quot;,$queries) . &quot; &quot; . $suffix . &quot;;&quot;;

    return $query;
}

/**
 * @param string $str string to escape for intended use
 * @return string
 */
function escape($str)
{
    return mysql_real_escape_string($str);
}
&lt;/code&gt;&lt;/pre&gt;
</pre>
<p>于是，我们可以这样使用：（<code>为什么我们要在update语句后加上“Limit 1”呢？这个关系到性能问题，关于这方面的话题，你可以查看本站的《<a title="MySQL性能优化的最佳20+条经验" href="https://coolshell.cn/articles/1846.html">MySQL性能优化的最佳20+条经验</a>》</code>）</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
&lt;pre&gt;&lt;code&gt;$updates = array(
    &#039;field1&#039;=&gt;&#039;val1&#039;
    &#039;field2&#039;=&gt;&#039;val2&#039;
);
$wheres = array(
    &#039;field1&#039;=&gt;&#039;cond1&#039;,
    &#039;field2&#039;=&gt;&#039;cond2&#039;
);
echo construct_sql(construct_sql(&quot;UPDATE table SET&quot;, &quot;, &quot;, $updates) . &quot; WHERE &quot;, &quot; AND &quot;, $wheres),&quot;LIMIT 1&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;/pre&gt;
</pre>
<p><code>下面是输出结果：</code></p>
<p><code data-enlighter-language="php" class="EnlighterJSRAW">UPDATE table SET `field1`=&#039;val1&#039;, `field2`=&#039;val2&#039; WHERE `field1`=&#039;cond1&#039; AND `field2`=&#039;cond2&#039; LIMIT 1;</code></p>
<p> </p>
<p><code>（全文完）</code><!--



<p align="center"><a href= target=_blank><img decoding="async" src=""></a></p>





<p align="center"><img decoding="async" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.weixin.jpg"> <img decoding="async" loading="lazy" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.mini_.jpg" width="300" height="300"> <br />关注CoolShell微信公众账号和微信小程序</p>

 

--></p>
<div style="margin-top: 15px; font-size: 16px;color: #cc0000;">
<p align="center"><strong>（转载本站文章请注明作者和出处 <a href="https://coolshell.cn/">酷 壳 &#8211; CoolShell</a> ，请勿用于任何商业用途）</strong></p>
</div>

<div class="wp_rp_wrap  wp_rp_vertical_m" ><div class="wp_rp_content"><h3 class="related_post_title">相关文章</h3><ul class="related_post wp_rp"><li ><a href="https://coolshell.cn/articles/7270.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/05/overview2-1-150x150.png" alt="NoSQL 数据建模技术" width="150" height="150" /></a><a href="https://coolshell.cn/articles/7270.html" class="wp_rp_title">NoSQL 数据建模技术</a></li><li ><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/7.jpg" alt="开源中最好的Web开发的资源" width="150" height="150" /></a><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_title">开源中最好的Web开发的资源</a></li><li ><a href="https://coolshell.cn/articles/1846.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2009/11/unoptimized_explain-150x150.jpg" alt="MySQL性能优化的最佳20+条经验" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1846.html" class="wp_rp_title">MySQL性能优化的最佳20+条经验</a></li><li ><a href="https://coolshell.cn/articles/8711.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/12/200906020837401710-150x150.jpg" alt="程序员疫苗：代码注入" width="150" height="150" /></a><a href="https://coolshell.cn/articles/8711.html" class="wp_rp_title">程序员疫苗：代码注入</a></li><li ><a href="https://coolshell.cn/articles/7886.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/07/muxnt-150x150.jpg" alt="代码执行的效率" width="150" height="150" /></a><a href="https://coolshell.cn/articles/7886.html" class="wp_rp_title">代码执行的效率</a></li><li ><a href="https://coolshell.cn/articles/7490.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/06/f1-150x150.jpg" alt="性能调优攻略" width="150" height="150" /></a><a href="https://coolshell.cn/articles/7490.html" class="wp_rp_title">性能调优攻略</a></li></ul></div></div>The post <a href="https://coolshell.cn/articles/1889.html">SQL的Where语句</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></content:encoded>
					
					<wfw:commentRss>https://coolshell.cn/articles/1889.html/feed</wfw:commentRss>
			<slash:comments>20</slash:comments>
		
		
			</item>
		<item>
		<title>MySQL性能优化的最佳20+条经验</title>
		<link>https://coolshell.cn/articles/1846.html</link>
					<comments>https://coolshell.cn/articles/1846.html#comments</comments>
		
		<dc:creator><![CDATA[陈皓]]></dc:creator>
		<pubDate>Fri, 27 Nov 2009 10:57:33 +0000</pubDate>
				<category><![CDATA[PHP脚本]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<guid isPermaLink="false">http://coolshell.cn/?p=1846</guid>

					<description><![CDATA[<p>今天，数据库的操作越来越成为整个应用的性能瓶颈了，这点对于Web应用尤其明显。关于数据库的性能，这并不只是DBA才需要担心的事，而这更是我们程序员需要去关注的事...</p>
<p class="read-more"><a class="btn btn-default" href="https://coolshell.cn/articles/1846.html"> Read More<span class="screen-reader-text">  Read More</span></a></p>
The post <a href="https://coolshell.cn/articles/1846.html">MySQL性能优化的最佳20+条经验</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></description>
										<content:encoded><![CDATA[<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415450859608158"
     crossorigin="anonymous"></script>今天，数据库的操作越来越成为整个应用的性能瓶颈了，这点对于Web应用尤其明显。关于数据库的性能，这并不只是DBA才需要担心的事，而这更是我们程序员需要去关注的事情。当我们去设计数据库表结构，对操作数据库时（尤其是查表时的SQL语句），我们都需要注意数据操作的性能。这里，我们不会讲过多的SQL语句的优化，而只是针对MySQL这一Web应用最多的数据库。希望下面的这些优化技巧对你有用。</p>
<h4>1. 为查询缓存优化你的查询</h4>
<p>大多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一，而且这是被MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次的时候，这些查询结果会被放到一个缓存中，这样，后续的相同的查询就不用操作表而直接访问缓存结果了。</p>
<p>这里最主要的问题是，对于程序员来说，这个事情是很容易被忽略的。因为，我们某些查询语句会让MySQL不使用缓存。请看下面的示例：</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
// 查询缓存不开启
$r = mysql_query(&quot;SELECT username FROM user WHERE signup_date &gt;= CURDATE()&quot;);

// 开启查询缓存
$today = date(&quot;Y-m-d&quot;);
$r = mysql_query(&quot;SELECT username FROM user WHERE signup_date &gt;= &#039;$today&#039;&quot;);
</pre>
<p>上面两条SQL语句的差别就是 CURDATE() ，MySQL的查询缓存对这个函数不起作用。所以，像 NOW() 和 RAND() 或是其它的诸如此类的SQL函数都不会开启查询缓存，因为这些函数的返回是会不定的易变的。所以，你所需要的就是用一个变量来代替MySQL的函数，从而开启缓存。</p>
<p><span id="more-1846"></span></p>
<h4>2. EXPLAIN 你的 SELECT 查询</h4>
<p>使用 <a href="http://dev.mysql.com/doc/refman/5.0/en/explain.html" target="_blank">EXPLAIN</a> 关键字可以让你知道MySQL是如何处理你的SQL语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。</p>
<p>EXPLAIN 的查询结果还会告诉你你的索引主键被如何利用的，你的数据表是如何被搜索和排序的……等等，等等。</p>
<p>挑一个你的SELECT语句（推荐挑选那个最复杂的，有多表联接的），把关键字EXPLAIN加到前面。你可以使用phpmyadmin来做这个事。然后，你会看到一张表格。下面的这个示例中，我们忘记加上了group_id索引，并且有表联接：</p>
<div class="tutorial_image"><img decoding="async" src="http://nettuts.s3.amazonaws.com/500_mysql/unoptimized_explain.jpg" border="0" alt="" /></div>
<p>当我们为 group_id 字段加上索引后：</p>
<div class="tutorial_image"><img decoding="async" src="http://nettuts.s3.amazonaws.com/500_mysql/optimized_explain.jpg" border="0" alt="" /></div>
<p>我们可以看到，前一个结果显示搜索了 7883 行，而后一个只是搜索了两个表的 9 和 16 行。查看rows列可以让我们找到潜在的性能问题。</p>
<h4>3. 当只要一行数据时使用 LIMIT 1</h4>
<p>当你查询表的有些时候，你已经知道结果只会有一条结果，但因为你可能需要去fetch游标，或是你也许会去检查返回的记录数。</p>
<p>在这种情况下，加上 LIMIT 1 可以增加性能。这样一样，MySQL数据库引擎会在找到一条数据后停止搜索，而不是继续往后查少下一条符合记录的数据。</p>
<p>下面的示例，只是为了找一下是否有“中国”的用户，很明显，后面的会比前面的更有效率。（请注意，第一条中是Select *，第二条是Select 1）</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">

// 没有效率的：
$r = mysql_query(&quot;SELECT * FROM user WHERE country = &#039;China&#039;&quot;);
if (mysql_num_rows($r) &gt; 0) {
	// ...
}

// 有效率的：
$r = mysql_query(&quot;SELECT 1 FROM user WHERE country = &#039;China&#039; LIMIT 1&quot;);
if (mysql_num_rows($r) &gt; 0) {
	// ...
}
</pre>
<h4>4. 为搜索字段建索引</h4>
<p>索引并不一定就是给主键或是唯一的字段。如果在你的表中，有某个字段你总要会经常用来做搜索，那么，请为其建立索引吧。</p>
<div class="tutorial_image"><img decoding="async" src="http://nettuts.s3.amazonaws.com/500_mysql/search_index.jpg" border="0" alt="" /></div>
<p>从上图你可以看到那个搜索字串 &#8220;last_name LIKE &#8216;a%'&#8221;，一个是建了索引，一个是没有索引，性能差了4倍左右。</p>
<p>另外，你应该也需要知道什么样的搜索是不能使用正常的索引的。例如，当你需要在一篇大的文章中搜索一个词时，如： &#8220;WHERE post_content LIKE &#8216;%apple%'&#8221;，索引可能是没有意义的。你可能需要使用<a href="http://dev.mysql.com/doc/refman/5.1/en/fulltext-search.html" target="_blank">MySQL全文索引</a> 或是自己做一个索引（比如说：搜索关键词或是Tag什么的）</p>
<h4>5. 在Join表的时候使用相当类型的例，并将其索引</h4>
<p>如果你的应用程序有很多 JOIN 查询，你应该确认两个表中Join的字段是被建过索引的。这样，MySQL内部会启动为你优化Join的SQL语句的机制。</p>
<p>而且，这些被用来Join的字段，应该是相同的类型的。例如：如果你要把 DECIMAL 字段和一个 INT 字段Join在一起，MySQL就无法使用它们的索引。对于那些STRING类型，还需要有相同的字符集才行。（两个表的字符集有可能不一样）</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
// 在state中查找company
$r = mysql_query(&quot;SELECT company_name FROM users
	LEFT JOIN companies ON (users.state = companies.state)
	WHERE users.id = $user_id&quot;);

// 两个 state 字段应该是被建过索引的，而且应该是相当的类型，相同的字符集。
</pre>
<h4>6. 千万不要 ORDER BY RAND()</h4>
<p>想打乱返回的数据行？随机挑一个数据？真不知道谁发明了这种用法，但很多新手很喜欢这样用。但你确不了解这样做有多么可怕的性能问题。</p>
<p>如果你真的想把返回的数据行打乱了，你有N种方法可以达到这个目的。这样使用只让你的数据库的性能呈指数级的下降。这里的问题是：MySQL会不得不去执行RAND()函数（很耗CPU时间），而且这是为了每一行记录去记行，然后再对其排序。就算是你用了Limit 1也无济于事（因为要排序）</p>
<p>下面的示例是随机挑一条记录</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
// 千万不要这样做：
$r = mysql_query(&quot;SELECT username FROM user ORDER BY RAND() LIMIT 1&quot;);

// 这要会更好：
$r = mysql_query(&quot;SELECT count(*) FROM user&quot;);
$d = mysql_fetch_row($r);
$rand = mt_rand(0,$d[0] - 1);

$r = mysql_query(&quot;SELECT username FROM user LIMIT $rand, 1&quot;);
</pre>
<h4>7. 避免 SELECT *</h4>
<p>从数据库里读出越多的数据，那么查询就会变得越慢。并且，如果你的数据库服务器和WEB服务器是两台独立的服务器的话，这还会增加网络传输的负载。</p>
<p>所以，你应该养成一个需要什么就取什么的好的习惯。</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
// 不推荐
$r = mysql_query(&quot;SELECT * FROM user WHERE user_id = 1&quot;);
$d = mysql_fetch_assoc($r);
echo &quot;Welcome {$d[&#039;username&#039;]}&quot;;

// 推荐
$r = mysql_query(&quot;SELECT username FROM user WHERE user_id = 1&quot;);
$d = mysql_fetch_assoc($r);
echo &quot;Welcome {$d[&#039;username&#039;]}&quot;;
</pre>
<h4>8. 永远为每张表设置一个ID</h4>
<p>我们应该为数据库里的每张表都设置一个ID做为其主键，而且最好的是一个INT型的（推荐使用UNSIGNED），并设置上自动增加的AUTO_INCREMENT标志。</p>
<p>就算是你 users 表有一个主键叫 “email”的字段，你也别让它成为主键。使用 VARCHAR 类型来当主键会使用得性能下降。另外，在你的程序中，你应该使用表的ID来构造你的数据结构。</p>
<p>而且，在MySQL数据引擎下，还有一些操作需要使用主键，在这些情况下，主键的性能和设置变得非常重要，比如，集群，分区……</p>
<p>在这里，只有一个情况是例外，那就是“关联表”的“外键”，也就是说，这个表的主键，通过若干个别的表的主键构成。我们把这个情况叫做“外键”。比如：有一个“学生表”有学生的ID，有一个“课程表”有课程ID，那么，“成绩表”就是“关联表”了，其关联了学生表和课程表，在成绩表中，学生ID和课程ID叫“外键”其共同组成主键。</p>
<h4>9. 使用 ENUM 而不是 VARCHAR</h4>
<p><a href="http://dev.mysql.com/doc/refman/5.0/en/enum.html" target="_blank">ENUM</a> 类型是非常快和紧凑的。在实际上，其保存的是 TINYINT，但其外表上显示为字符串。这样一来，用这个字段来做一些选项列表变得相当的完美。</p>
<p>如果你有一个字段，比如“性别”，“国家”，“民族”，“状态”或“部门”，你知道这些字段的取值是有限而且固定的，那么，你应该使用 ENUM 而不是 VARCHAR。</p>
<p>MySQL也有一个“建议”（见第十条）告诉你怎么去重新组织你的表结构。当你有一个 VARCHAR 字段时，这个建议会告诉你把其改成 ENUM 类型。使用 PROCEDURE ANALYSE() 你可以得到相关的建议。</p>
<h4>10. 从 PROCEDURE ANALYSE() 取得建议</h4>
<p><a href="http://dev.mysql.com/doc/refman/5.0/en/procedure-analyse.html" target="_blank">PROCEDURE ANALYSE()</a> 会让 MySQL 帮你去分析你的字段和其实际的数据，并会给你一些有用的建议。只有表中有实际的数据，这些建议才会变得有用，因为要做一些大的决定是需要有数据作为基础的。</p>
<p>例如，如果你创建了一个 INT 字段作为你的主键，然而并没有太多的数据，那么，PROCEDURE ANALYSE()会建议你把这个字段的类型改成 MEDIUMINT 。或是你使用了一个 VARCHAR 字段，因为数据不多，你可能会得到一个让你把它改成 ENUM 的建议。这些建议，都是可能因为数据不够多，所以决策做得就不够准。</p>
<p>在phpmyadmin里，你可以在查看表时，点击 &#8220;Propose table structure&#8221; 来查看这些建议</p>
<div class="tutorial_image"><img decoding="async" src="http://nettuts.s3.amazonaws.com/500_mysql/suggestions.jpg" border="0" alt="" /></div>
<p>一定要注意，这些只是建议，只有当你的表里的数据越来越多时，这些建议才会变得准确。一定要记住，你才是最终做决定的人。</p>
<h4>11. 尽可能的使用 NOT NULL</h4>
<p>除非你有一个很特别的原因去使用 NULL 值，你应该总是让你的字段保持 NOT NULL。这看起来好像有点争议，请往下看。</p>
<p>首先，问问你自己“Empty”和“NULL”有多大的区别（如果是INT，那就是0和NULL）？如果你觉得它们之间没有什么区别，那么你就不要使用NULL。（你知道吗？在 Oracle 里，NULL 和 Empty 的字符串是一样的！)</p>
<p>不要以为 NULL 不需要空间，其需要额外的空间，并且，在你进行比较的时候，你的程序会更复杂。 当然，这里并不是说你就不能使用NULL了，现实情况是很复杂的，依然会有些情况下，你需要使用NULL值。</p>
<p>下面摘自MySQL自己的文档：</p>
<blockquote><p>&#8220;NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.&#8221;</p></blockquote>
<h4>12. Prepared Statements</h4>
<p>Prepared Statements很像存储过程，是一种运行在后台的SQL语句集合，我们可以从使用 prepared statements 获得很多好处，无论是性能问题还是安全问题。</p>
<p>Prepared Statements 可以检查一些你绑定好的变量，这样可以保护你的程序不会受到“SQL注入式”攻击。当然，你也可以手动地检查你的这些变量，然而，手动的检查容易出问题，而且很经常会被程序员忘了。当我们使用一些framework或是ORM的时候，这样的问题会好一些。</p>
<p>在性能方面，当一个相同的查询被使用多次的时候，这会为你带来可观的性能优势。你可以给这些Prepared Statements定义一些参数，而MySQL只会解析一次。</p>
<p>虽然最新版本的MySQL在传输Prepared Statements是使用二进制形势，所以这会使得网络传输非常有效率。</p>
<p>当然，也有一些情况下，我们需要避免使用Prepared Statements，因为其不支持查询缓存。但据说版本5.1后支持了。</p>
<p>在PHP中要使用prepared statements，你可以查看其使用手册：<a href="http://php.net/manual/en/book.mysqli.php" target="_blank">mysqli 扩展</a> 或是使用数据库抽象层，如： <a href="http://us.php.net/manual/en/book.pdo.php" target="_blank">PDO</a>.</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
// 创建 prepared statement
if ($stmt = $mysqli-&gt;prepare(&quot;SELECT username FROM user WHERE state=?&quot;)) {

	// 绑定参数
    $stmt-&gt;bind_param(&quot;s&quot;, $state);

	// 执行
    $stmt-&gt;execute();

	// 绑定结果
    $stmt-&gt;bind_result($username);

	// 移动游标
    $stmt-&gt;fetch();

    printf(&quot;%s is from %s\n&quot;, $username, $state);

    $stmt-&gt;close();
}
</pre>
<h4>13. 无缓冲的查询</h4>
<p>正常的情况下，当你在当你在你的脚本中执行一个SQL语句的时候，你的程序会停在那里直到没这个SQL语句返回，然后你的程序再往下继续执行。你可以使用无缓冲查询来改变这个行为。</p>
<p>关于这个事情，在PHP的文档中有一个非常不错的说明： <a href="http://php.net/manual/en/function.mysql-unbuffered-query.php" target="_blank">mysql_unbuffered_query()</a> 函数：</p>
<blockquote><p>&#8220;mysql_unbuffered_query() sends the SQL query query to MySQL without automatically fetching and buffering the result rows as mysql_query() does. This saves a considerable amount of memory with SQL queries that produce large result sets, and you can start working on the result set immediately after the first row has been retrieved as you don&#8217;t have to wait until the complete SQL query has been performed.&#8221;</p></blockquote>
<p>上面那句话翻译过来是说，mysql_unbuffered_query() 发送一个SQL语句到MySQL而并不像mysql_query()一样去自动fethch和缓存结果。这会相当节约很多可观的内存，尤其是那些会产生大量结果的查询语句，并且，你不需要等到所有的结果都返回，只需要第一行数据返回的时候，你就可以开始马上开始工作于查询结果了。</p>
<p>然而，这会有一些限制。因为你要么把所有行都读走，或是你要在进行下一次的查询前调用 <a href="http://us2.php.net/manual/en/function.mysql-free-result.php" target="_blank">mysql_free_result()</a> 清除结果。而且， <a href="http://us2.php.net/manual/en/function.mysql-num-rows.php" target="_blank">mysql_num_rows()</a> 或 <a href="http://us2.php.net/manual/en/function.mysql-data-seek.php" target="_blank">mysql_data_seek()</a> 将无法使用。所以，是否使用无缓冲的查询你需要仔细考虑。</p>
<h4>14. 把IP地址存成 UNSIGNED INT</h4>
<p>很多程序员都会创建一个 VARCHAR(15) 字段来存放字符串形式的IP而不是整形的IP。如果你用整形来存放，只需要4个字节，并且你可以有定长的字段。而且，这会为你带来查询上的优势，尤其是当你需要使用这样的WHERE条件：IP between ip1 and ip2。</p>
<p>我们必需要使用UNSIGNED INT，因为 IP地址会使用整个32位的无符号整形。</p>
<p>而你的查询，你可以使用 <a href="http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-aton" target="_blank">INET_ATON()</a> 来把一个字符串IP转成一个整形，并使用 <a href="http://dev.mysql.com/doc/refman/5.0/en/miscellaneous-functions.html#function_inet-ntoa" target="_blank">INET_NTOA()</a> 把一个整形转成一个字符串IP。在PHP中，也有这样的函数 <a href="http://php.net/manual/en/function.ip2long.php" target="_blank">ip2long()</a> 和 <a href="http://us.php.net/manual/en/function.long2ip.php" target="_blank">long2ip()</a>。</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
$r = &quot;UPDATE users SET ip = INET_ATON(&#039;{$_SERVER[&#039;REMOTE_ADDR&#039;]}&#039;) WHERE user_id = $user_id&quot;;
</pre>
<h4>15. 固定长度的表会更快</h4>
<p>如果表中的所有字段都是“固定长度”的，整个表会被认为是 <a href="http://dev.mysql.com/doc/refman/5.1/en/static-format.html" target="_blank">&#8220;static&#8221; 或 &#8220;fixed-length&#8221;</a>。 例如，表中没有如下类型的字段： VARCHAR，TEXT，BLOB。只要你包括了其中一个这些字段，那么这个表就不是“固定长度静态表”了，这样，MySQL 引擎会用另一种方法来处理。</p>
<p>固定长度的表会提高性能，因为MySQL搜寻得会更快一些，因为这些固定的长度是很容易计算下一个数据的偏移量的，所以读取的自然也会很快。而如果字段不是定长的，那么，每一次要找下一条的话，需要程序找到主键。</p>
<p>并且，固定长度的表也更容易被缓存和重建。不过，唯一的副作用是，固定长度的字段会浪费一些空间，因为定长的字段无论你用不用，他都是要分配那么多的空间。</p>
<p>使用“垂直分割”技术（见下一条），你可以分割你的表成为两个一个是定长的，一个则是不定长的。</p>
<h4>16. 垂直分割</h4>
<p>“垂直分割”是一种把数据库中的表按列变成几张表的方法，这样可以降低表的复杂度和字段的数目，从而达到优化的目的。（以前，在银行做过项目，见过一张表有100多个字段，很恐怖）</p>
<p><strong>示例一</strong>：在Users表中有一个字段是家庭地址，这个字段是可选字段，相比起，而且你在数据库操作的时候除了个人信息外，你并不需要经常读取或是改写这个字段。那么，为什么不把他放到另外一张表中呢？ 这样会让你的表有更好的性能，大家想想是不是，大量的时候，我对于用户表来说，只有用户ID，用户名，口令，用户角色等会被经常使用。小一点的表总是会有好的性能。</p>
<p><strong>示例二</strong>： 你有一个叫 &#8220;last_login&#8221; 的字段，它会在每次用户登录时被更新。但是，每次更新时会导致该表的查询缓存被清空。所以，你可以把这个字段放到另一个表中，这样就不会影响你对用户ID，用户名，用户角色的不停地读取了，因为查询缓存会帮你增加很多性能。</p>
<p>另外，你需要注意的是，这些被分出去的字段所形成的表，你不会经常性地去Join他们，不然的话，这样的性能会比不分割时还要差，而且，会是极数级的下降。</p>
<h4>17. 拆分大的 DELETE 或 INSERT 语句</h4>
<p>如果你需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询，你需要非常小心，要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的，表一锁住了，别的操作都进不来了。</p>
<p>Apache 会有很多的子进程或线程。所以，其工作起来相当有效率，而我们的服务器也不希望有太多的子进程，线程和数据库链接，这是极大的占服务器资源的事情，尤其是内存。</p>
<p>如果你把你的表锁上一段时间，比如30秒钟，那么对于一个有很高访问量的站点来说，这30秒所积累的访问进程/线程，数据库链接，打开的文件数，可能不仅仅会让你泊WEB服务Crash，还可能会让你的整台服务器马上掛了。</p>
<p>所以，如果你有一个大的处理，你定你一定把其拆分，使用 LIMIT 条件是一个好的方法。下面是一个示例：</p>
<pre data-enlighter-language="php" class="EnlighterJSRAW">
while (1) {
    //每次只做1000条
	mysql_query(&quot;DELETE FROM logs WHERE log_date &lt;= &#039;2009-11-01&#039; LIMIT 1000&quot;);
	if (mysql_affected_rows() == 0) {
		// 没得可删了，退出！
		break;
	}
	// 每次都要休息一会儿
	usleep(50000);
}
</pre>
<h4>18. 越小的列会越快</h4>
<p>对于大多数的数据库引擎来说，硬盘操作可能是最重大的瓶颈。所以，把你的数据变得紧凑会对这种情况非常有帮助，因为这减少了对硬盘的访问。</p>
<p>参看 MySQL 的文档 <a href="http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html" target="_blank">Storage Requirements</a> 查看所有的数据类型。</p>
<p>如果一个表只会有几列罢了（比如说字典表，配置表），那么，我们就没有理由使用 INT 来做主键，使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果你不需要记录时间，使用 DATE 要比 DATETIME 好得多。</p>
<p>当然，你也需要留够足够的扩展空间，不然，你日后来干这个事，你会死的很难看，参看<a href="http://news.slashdot.org/article.pl?sid=06/11/09/1534204" target="_blank">Slashdot的例子</a>（2009年11月06日），一个简单的ALTER TABLE语句花了3个多小时，因为里面有一千六百万条数据。</p>
<h4>19. 选择正确的存储引擎</h4>
<p>在 MySQL 中有两个存储引擎 MyISAM 和 InnoDB，每个引擎都有利有弊。酷壳以前文章《<a href="https://coolshell.cn/articles/652.html" target="_blank">MySQL: InnoDB 还是 MyISAM?</a>》讨论和这个事情。</p>
<p>MyISAM 适合于一些需要大量查询的应用，但其对于有大量写操作并不是很好。甚至你只是需要update一个字段，整个表都会被锁起来，而别的进程，就算是读进程都无法操作直到读操作完成。另外，MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。</p>
<p>InnoDB 的趋势会是一个非常复杂的存储引擎，对于一些小的应用，它会比 MyISAM 还慢。他是它支持“行锁” ，于是在写操作比较多的时候，会更优秀。并且，他还支持更多的高级应用，比如：事务。</p>
<p>下面是MySQL的手册</p>
<ul>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/myisam-storage-engine.html">target=&#8221;_blank&#8221;MyISAM Storage Engine</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/innodb.html" target="_blank">InnoDB Storage Engine</a></li>
</ul>
<h4>20. 使用一个对象关系映射器（Object Relational Mapper）</h4>
<p>使用 ORM (Object Relational Mapper)，你能够获得可靠的性能增涨。一个ORM可以做的所有事情，也能被手动的编写出来。但是，这需要一个高级专家。</p>
<p>ORM 的最重要的是“Lazy Loading”，也就是说，只有在需要的去取值的时候才会去真正的去做。但你也需要小心这种机制的副作用，因为这很有可能会因为要去创建很多很多小的查询反而会降低性能。</p>
<p>ORM 还可以把你的SQL语句打包成一个事务，这会比单独执行他们快得多得多。</p>
<p>目前，个人最喜欢的PHP的ORM是：<a href="http://www.doctrine-project.org" target="_blank">Doctrine</a>。</p>
<h4>21. 小心“永久链接”</h4>
<p>“永久链接”的目的是用来减少重新创建MySQL链接的次数。当一个链接被创建了，它会永远处在连接的状态，就算是数据库操作已经结束了。而且，自从我们的Apache开始重用它的子进程后——也就是说，下一次的HTTP请求会重用Apache的子进程，并重用相同的 MySQL 链接。</p>
<ul>
<li><a href="http://php.net/manual/en/function.mysql-pconnect.php" target="_blank">PHP手册：mysql_pconnect() </a></li>
</ul>
<p>在理论上来说，这听起来非常的不错。但是从个人经验（也是大多数人的）上来说，这个功能制造出来的麻烦事更多。因为，你只有有限的链接数，内存问题，文件句柄数，等等。</p>
<p>而且，Apache 运行在极端并行的环境中，会创建很多很多的了进程。这就是为什么这种“永久链接”的机制工作地不好的原因。在你决定要使用“永久链接”之前，你需要好好地考虑一下你的整个系统的架构。</p>
<p>文章：<a href="http://net.tutsplus.com/tutorials/other/top-20-mysql-best-practices/" target="_blank">来源</a></p>
<p>（全文完）<!--



<p align="center"><a href= target=_blank><img decoding="async" src=""></a></p>





<p align="center"><img decoding="async" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.weixin.jpg"> <img decoding="async" loading="lazy" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.mini_.jpg" width="300" height="300"> <br />关注CoolShell微信公众账号和微信小程序</p>

 

--></p>
<div style="margin-top: 15px; font-size: 16px;color: #cc0000;">
<p align="center"><strong>（转载本站文章请注明作者和出处 <a href="https://coolshell.cn/">酷 壳 &#8211; CoolShell</a> ，请勿用于任何商业用途）</strong></p>
</div>

<div class="wp_rp_wrap  wp_rp_vertical_m" ><div class="wp_rp_content"><h3 class="related_post_title">相关文章</h3><ul class="related_post wp_rp"><li ><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/7.jpg" alt="开源中最好的Web开发的资源" width="150" height="150" /></a><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_title">开源中最好的Web开发的资源</a></li><li ><a href="https://coolshell.cn/articles/3684.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2011/02/1128-150x150.jpg" alt="Web开发人员速查卡" width="150" height="150" /></a><a href="https://coolshell.cn/articles/3684.html" class="wp_rp_title">Web开发人员速查卡</a></li><li ><a href="https://coolshell.cn/articles/1889.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2009/12/sql.where_.clause-150x150.jpg" alt="SQL的Where语句" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1889.html" class="wp_rp_title">SQL的Where语句</a></li><li ><a href="https://coolshell.cn/articles/652.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/17.jpg" alt="MySQL: InnoDB 还是 MyISAM?" width="150" height="150" /></a><a href="https://coolshell.cn/articles/652.html" class="wp_rp_title">MySQL: InnoDB 还是 MyISAM?</a></li><li ><a href="https://coolshell.cn/articles/7886.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/07/muxnt-150x150.jpg" alt="代码执行的效率" width="150" height="150" /></a><a href="https://coolshell.cn/articles/7886.html" class="wp_rp_title">代码执行的效率</a></li><li ><a href="https://coolshell.cn/articles/7490.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/06/f1-150x150.jpg" alt="性能调优攻略" width="150" height="150" /></a><a href="https://coolshell.cn/articles/7490.html" class="wp_rp_title">性能调优攻略</a></li></ul></div></div>The post <a href="https://coolshell.cn/articles/1846.html">MySQL性能优化的最佳20+条经验</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></content:encoded>
					
					<wfw:commentRss>https://coolshell.cn/articles/1846.html/feed</wfw:commentRss>
			<slash:comments>169</slash:comments>
		
		
			</item>
		<item>
		<title>MySQL: InnoDB 还是 MyISAM?</title>
		<link>https://coolshell.cn/articles/652.html</link>
					<comments>https://coolshell.cn/articles/652.html#comments</comments>
		
		<dc:creator><![CDATA[陈皓]]></dc:creator>
		<pubDate>Fri, 24 Apr 2009 06:33:09 +0000</pubDate>
				<category><![CDATA[技术读物]]></category>
		<category><![CDATA[数据库]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[InnoDB]]></category>
		<category><![CDATA[MyISAM]]></category>
		<category><![CDATA[MySQL]]></category>
		<guid isPermaLink="false">http://coolshell.cn/?p=652</guid>

					<description><![CDATA[<p>MyISAM 是MySQL中默认的存储引擎，一般来说不是有太多人关心这个东西。决定使用什么样的存储引擎是一个很tricky的事情，但是还是值我们去研究一下，这里...</p>
<p class="read-more"><a class="btn btn-default" href="https://coolshell.cn/articles/652.html"> Read More<span class="screen-reader-text">  Read More</span></a></p>
The post <a href="https://coolshell.cn/articles/652.html">MySQL: InnoDB 还是 MyISAM?</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></description>
										<content:encoded><![CDATA[<p><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-3415450859608158"
     crossorigin="anonymous"></script>MyISAM 是MySQL中默认的存储引擎，一般来说不是有太多人关心这个东西。决定使用什么样的存储引擎是一个很tricky的事情，但是还是值我们去研究一下，这里的文章只考虑 MyISAM 和InnoDB这两个，因为这两个是最常见的。</p>
<p>下面先让我们回答一些问题：</p>
<ul>
<li>你的数据库有外键吗？</li>
<li>你需要事务支持吗？</li>
<li>你需要全文索引吗？</li>
<li>你经常使用什么样的查询模式？</li>
<li>你的数据有多大？</li>
</ul>
<p><span id="more-652"></span></p>
<p>思考上面这些问题可以让你找到合适的方向，但那并不是绝对的。如果你需要事务处理或是外键，那么InnoDB 可能是比较好的方式。如果你需要全文索引，那么通常来说 MyISAM是好的选择，因为这是系统内建的，然而，我们其实并不会经常地去测试两百万行记录。所以，就算是慢一点，我们可以通过使用Sphinx从InnoDB中获得全文索引。</p>
<p>数据的大小，是一个影响你选择什么样存储引擎的重要因素，大尺寸的数据集趋向于选择InnoDB方式，因为其支持事务处理和故障恢复。数据库的在小决定了故障恢复的时间长短，InnoDB可以利用事务日志进行数据恢复，这会比较快。而MyISAM可能会需要几个小时甚至几天来干这些事，InnoDB只需要几分钟。</p>
<p>您操作数据库表的习惯可能也会是一个对性能影响很大的因素。比如： COUNT() 在 MyISAM 表中会非常快，而在InnoDB 表下可能会很痛苦。而主键查询则在InnoDB下会相当相当的快，但需要小心的是如果我们的主键太长了也会导致性能问题。大批的inserts 语句在MyISAM下会快一些，但是updates 在InnoDB 下会更快一些——尤其在并发量大的时候。</p>
<p>所以，到底你检使用哪一个呢？根据经验来看，如果是一些小型的应用或项目，那么MyISAM 也许会更适合。当然，在大型的环境下使用MyISAM 也会有很大成功的时候，但却不总是这样的。如果你正在计划使用一个超大数据量的项目，而且需要事务处理或外键支持，那么你真的应该直接使用InnoDB方式。但需要记住InnoDB 的表需要更多的内存和存储，转换100GB 的MyISAM 表到InnoDB 表可能会让你有非常坏的体验。</p>
<p style="display: none;"><img decoding="async" loading="lazy" style="display: none; width: 0px; height: 0px; border-style: none;" src="http://blog.inetu.net/wp-content/plugins/wp-spamfree/img/wpsf-img.php" alt="" width="0" height="0" /></p>
<p style="display: none;">文章：<a href="http://blog.inetu.net/2009/04/mysql-innodb-or-myisam/" target="_blank">来源</a></p>
<p><!--



<p align="center"><a href= target=_blank><img decoding="async" src=""></a></p>





<p align="center"><img decoding="async" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.weixin.jpg"> <img decoding="async" loading="lazy" src="https://coolshell.cn/wp-content/uploads/2020/03/coolshell.mini_.jpg" width="300" height="300"> <br />关注CoolShell微信公众账号和微信小程序</p>

 

--></p>
<div style="margin-top: 15px; font-size: 16px;color: #cc0000;">
<p align="center"><strong>（转载本站文章请注明作者和出处 <a href="https://coolshell.cn/">酷 壳 &#8211; CoolShell</a> ，请勿用于任何商业用途）</strong></p>
</div>

<div class="wp_rp_wrap  wp_rp_vertical_m" ><div class="wp_rp_content"><h3 class="related_post_title">相关文章</h3><ul class="related_post wp_rp"><li ><a href="https://coolshell.cn/articles/1846.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2009/11/unoptimized_explain-150x150.jpg" alt="MySQL性能优化的最佳20+条经验" width="150" height="150" /></a><a href="https://coolshell.cn/articles/1846.html" class="wp_rp_title">MySQL性能优化的最佳20+条经验</a></li><li ><a href="https://coolshell.cn/articles/7490.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/06/f1-150x150.jpg" alt="性能调优攻略" width="150" height="150" /></a><a href="https://coolshell.cn/articles/7490.html" class="wp_rp_title">性能调优攻略</a></li><li ><a href="https://coolshell.cn/articles/7270.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/uploads/2012/05/overview2-1-150x150.png" alt="NoSQL 数据建模技术" width="150" height="150" /></a><a href="https://coolshell.cn/articles/7270.html" class="wp_rp_title">NoSQL 数据建模技术</a></li><li ><a href="https://coolshell.cn/articles/5826.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/26.jpg" alt="千万别用MongoDB？真的吗？！" width="150" height="150" /></a><a href="https://coolshell.cn/articles/5826.html" class="wp_rp_title">千万别用MongoDB？真的吗？！</a></li><li ><a href="https://coolshell.cn/articles/4939.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/29.jpg" alt="Quora使用到的技术" width="150" height="150" /></a><a href="https://coolshell.cn/articles/4939.html" class="wp_rp_title">Quora使用到的技术</a></li><li ><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_thumbnail"><img src="https://coolshell.cn/wp-content/plugins/wordpress-23-related-posts-plugin/static/thumbs/7.jpg" alt="开源中最好的Web开发的资源" width="150" height="150" /></a><a href="https://coolshell.cn/articles/4795.html" class="wp_rp_title">开源中最好的Web开发的资源</a></li></ul></div></div>The post <a href="https://coolshell.cn/articles/652.html">MySQL: InnoDB 还是 MyISAM?</a> first appeared on <a href="https://coolshell.cn">酷 壳 - CoolShell</a>.]]></content:encoded>
					
					<wfw:commentRss>https://coolshell.cn/articles/652.html/feed</wfw:commentRss>
			<slash:comments>95</slash:comments>
		
		
			</item>
	</channel>
</rss>
