# 第äºç« ï¼æ°æ®æ¨¡åä¸æ¥è¯¢è¯è¨
![](img/ch2.png)
> è¯è¨çè¾¹çå°±æ¯ææ³çè¾¹çã
>
> ââ 路德维å¥Â·ç»´ç¹æ ¹æ¯å¦ï¼ãé»è¾å²å¦ãï¼1922ï¼
>
-------------------
[TOC]
æ°æ®æ¨¡åå¯è½æ¯è½¯ä»¶å¼åä¸æéè¦çé¨åäºï¼å 为å®ä»¬çå½±åå¦æ¤æ·±è¿ï¼ä¸ä»
ä»
å½±åç软件çç¼åæ¹å¼ï¼èä¸å½±åçæ们ç**解é¢æè·¯**ã
å¤æ°åºç¨ä½¿ç¨å±å±å å çæ°æ®æ¨¡åæ建ã对äºæ¯å±æ°æ®æ¨¡åçå
³é®é®é¢æ¯ï¼å®æ¯å¦ä½ç¨ä½ä¸å±æ°æ®æ¨¡åæ¥**表示**çï¼ä¾å¦ï¼
1. ä½ä¸ºä¸ååºç¨å¼å人åï¼ä½ è§å¯ç°å®ä¸çï¼éé¢æ人åï¼ç»ç»ï¼è´§ç©ï¼è¡ä¸ºï¼èµéæµåï¼ä¼ æå¨çï¼ï¼å¹¶éç¨å¯¹è±¡ææ°æ®ç»æï¼ä»¥åææ§é£äºæ°æ®ç»æçAPIæ¥è¿è¡å»ºæ¨¡ãé£äºç»æé常æ¯ç¹å®äºåºç¨ç¨åºçã
2. å½è¦åå¨é£äºæ°æ®ç»ææ¶ï¼ä½ å¯ä»¥å©ç¨éç¨æ°æ®æ¨¡åæ¥è¡¨ç¤ºå®ä»¬ï¼å¦JSONæXMLææ¡£ï¼å
³ç³»æ°æ®åºä¸ç表ãæå¾æ¨¡åã
3. æ°æ®åºè½¯ä»¶çå·¥ç¨å¸éå®å¦ä½ä»¥å
åãç£çæç½ç»ä¸çåèæ¥è¡¨ç¤ºJSON/XML/å
³ç³»/å¾æ°æ®ãè¿ç±»è¡¨ç¤ºå½¢å¼ä½¿æ°æ®æå¯è½ä»¥åç§æ¹å¼æ¥æ¥è¯¢ï¼æç´¢ï¼æ纵åå¤çã
4. å¨æ´ä½çå±æ¬¡ä¸ï¼ç¡¬ä»¶å·¥ç¨å¸å·²ç»æ³åºäºä½¿ç¨çµæµï¼å
èå²ï¼ç£åºæè
å
¶ä»ä¸è¥¿æ¥è¡¨ç¤ºåèçæ¹æ³ã
ä¸ä¸ªå¤æçåºç¨ç¨åºå¯è½ä¼ææ´å¤çä¸é´å±æ¬¡ï¼æ¯å¦åºäºAPIçAPIï¼ä¸è¿åºæ¬ææ³ä»ç¶æ¯ä¸æ ·çï¼æ¯ä¸ªå±é½éè¿æä¾ä¸ä¸ªæç¡®çæ°æ®æ¨¡åæ¥éèæ´ä½å±æ¬¡ä¸çå¤ææ§ãè¿äºæ½è±¡å
许ä¸åç人群ææå°åä½ï¼ä¾å¦æ°æ®åºååçå·¥ç¨å¸å使ç¨æ°æ®åºçåºç¨ç¨åºå¼å人åï¼ã
æ°æ®æ¨¡åç§ç±»ç¹å¤ï¼æ¯ä¸ªæ°æ®æ¨¡åé½å¸¦æå¦ä½ä½¿ç¨ç设æ³ãæäºç¨æ³å¾å®¹æï¼æäºåä¸æ¯æå¦æ¤ï¼æäºæä½è¿è¡å¾å¿«ï¼æäºå表ç°å¾å·®ï¼æäºæ°æ®è½¬æ¢é常èªç¶ï¼æäºåå¾éº»ç¦ã
ææ¡ä¸ä¸ªæ°æ®æ¨¡åéè¦è±è´¹å¾å¤ç²¾åï¼æ³æ³å
³ç³»æ°æ®å»ºæ¨¡æå¤å°æ¬ä¹¦ï¼ãå³ä¾¿åªä½¿ç¨ä¸ä¸ªæ°æ®æ¨¡åï¼ä¸ç¨æå¿å
¶å
é¨å·¥ä½æºå¶ï¼æ建软件ä¹æ¯é常å°é¾çãç¶èï¼å 为æ°æ®æ¨¡å对ä¸å±è½¯ä»¶çåè½ï¼è½åä»ä¹ï¼ä¸è½åä»ä¹ï¼æçè³æ·±çå½±åï¼æ以éæ©ä¸ä¸ªéåçæ°æ®æ¨¡åæ¯é常éè¦çã
å¨æ¬ç« ä¸ï¼æ们å°ç 究ä¸ç³»åç¨äºæ°æ®åå¨åæ¥è¯¢çéç¨æ°æ®æ¨¡åï¼åé¢å表ä¸ç第2ç¹ï¼ãç¹å«å°ï¼æ们å°æ¯è¾å
³ç³»æ¨¡åï¼æ档模ååå°éåºäºå¾å½¢çæ°æ®æ¨¡åãæ们è¿å°æ¥çåç§æ¥è¯¢è¯è¨å¹¶æ¯è¾å®ä»¬çç¨ä¾ãå¨ç¬¬3ç« ä¸ï¼æ们å°è®¨è®ºåå¨å¼ææ¯å¦ä½å·¥ä½çãä¹å°±æ¯è¯´ï¼è¿äºæ°æ®æ¨¡åå®é
ä¸æ¯å¦ä½å®ç°çï¼å表ä¸ç第3ç¹ï¼ã
## å
³ç³»æ¨¡åä¸æ档模å
ç°å¨æèåçæ°æ®æ¨¡åå¯è½æ¯SQLãå®åºäºEdgar Coddå¨1970å¹´æåºçå
³ç³»æ¨¡åã1ãï¼æ°æ®è¢«ç»ç»æ**å
³ç³»**ï¼SQLä¸ç§°ä½**表**ï¼ï¼å
¶ä¸æ¯ä¸ªå
³ç³»æ¯**å
ç»**ï¼SQLä¸ç§°ä½**è¡**)çæ åºéåã
å
³ç³»æ¨¡åæ¾æ¯ä¸ä¸ªç论æ§çæè®®ï¼å½æ¶å¾å¤äººé½æçæ¯å¦è½å¤ææå®ç°å®ãç¶èå°äº20ä¸çºª80年代ä¸æï¼å
³ç³»æ°æ®åºç®¡çç³»ç»ï¼RDBMSesï¼åSQLå·²æ为大å¤æ°äººä»¬åå¨åæ¥è¯¢æäºå¸¸è§ç»æçæ°æ®çé¦éå·¥å
·ãå
³ç³»æ°æ®åºå·²ç»æç»ç§°é¸äºå¤§çº¦25~30å¹´ââè¿å¯¹è®¡ç®æºå²æ¥è¯´æ¯æå
¶æ¼«é¿çæ¶é´ã
å
³ç³»æ°æ®åºèµ·æºäºåä¸æ°æ®å¤çï¼å¨20ä¸çºª60年代å70年代ç¨å¤§å计ç®æºæ¥æ§è¡ãä»ä»å¤©çè§åº¦æ¥çï¼é£äºç¨ä¾æ¾å¾å¾å¹³å¸¸ï¼å
¸åç**äºå¡å¤ç**ï¼å°éå®æé¶è¡äº¤æï¼èªç©ºå
¬å¸é¢è®¢ï¼åºå管çä¿¡æ¯è®°å½å¨åºï¼å**æ¹å¤ç**ï¼å®¢æ·å票ï¼å·¥èµåï¼æ¥åï¼ã
å½æ¶çå
¶ä»æ°æ®åºè¿«ä½¿åºç¨ç¨åºå¼å人åå¿
é¡»èèæ°æ®åºå
é¨çæ°æ®è¡¨ç¤ºå½¢å¼ãå
³ç³»æ¨¡åè´åäºå°ä¸è¿°å®ç°ç»èéèå¨æ´ç®æ´çæ¥å£ä¹åã
å¤å¹´æ¥ï¼å¨æ°æ®åå¨åæ¥è¯¢æ¹é¢åå¨ç许å¤ç¸äºç«äºçæ¹æ³ãå¨20ä¸çºª70年代å80年代åï¼ç½ç»æ¨¡åååå±æ¨¡åæ¾æ¯ä¸»è¦çéæ©ï¼ä½å
³ç³»æ¨¡åéåå æ®äºä¸»å¯¼å°ä½ã对象æ°æ®åºå¨20ä¸çºª80年代æ«å90年代åæ¥äºåå»ãXMLæ°æ®åºå¨äºåä¸ä¸çºªååºç°ï¼ä½åªæå°ä¼éç¨è¿ãå
³ç³»æ¨¡åçæ¯ä¸ªç«äºè
é½å¨å
¶æ¶ä»£äº§çäºå¤§éççä½ï¼ä½ä»æ¥æ²¡ææç»ã2ãã
éççµèè¶æ¥è¶å¼ºå¤§åäºèï¼å®ä»¬å¼å§ç¨äºæ¥çå¤æ ·åçç®çãå
³ç³»æ°æ®åºé常æåå°è¢«æ¨å¹¿å°ä¸å¡æ°æ®å¤ççåå§èå´ä¹å¤æ´ä¸ºå¹¿æ³çç¨ä¾ä¸ãä½ ä»å¤©å¨ç½ä¸çå°ç大é¨åå
容ä¾æ§æ¯ç±å
³ç³»æ°æ®åºæ¥æä¾æ¯æï¼æ 论æ¯å¨çº¿åå¸ï¼è®¨è®ºï¼ç¤¾äº¤ç½ç»ï¼çµååå¡ï¼æ¸¸æï¼è½¯ä»¶å³æå¡ç产ååºç¨ç¨åºççå
容ã
### NoSQLçè¯ç
ç°å¨ - 2010年代ï¼NoSQLå¼å§äºææ°ä¸è½®å°è¯ï¼è¯å¾æ¨ç¿»å
³ç³»æ¨¡åçç»æ²»å°ä½ãâNoSQLâè¿ä¸ªåå让人éæ¾ï¼å 为å®é
ä¸å®å¹¶æ²¡ææ¶åå°ä»»ä½ç¹å®çææ¯ãæåå®åªæ¯ä½ä¸ºä¸ä¸ªéç®çTwitteræ ç¾ï¼ç¨å¨2009å¹´ä¸ä¸ªå
³äºåå¸å¼ï¼éå
³ç³»æ°æ®åºä¸çå¼æºèä¼ä¸ãæ 论å¦ä½ï¼è¿ä¸ªæ¯è¯è§¦å¨äºæäºç¥ç»ï¼å¹¶è¿
éå¨ç½ç»åä¸ç¤¾åºå
å¤ä¼ æå¼æ¥ã好äºæ趣çæ°æ®åºç³»ç»ç°å¨é½ä¸*#NoSQL#*æ ç¾ç¸å
³èï¼å¹¶ä¸NoSQL被追溯æ§å°éæ°è§£é为**ä¸ä»
æ¯SQLï¼Not Only SQLï¼** ã4ãã
éç¨NoSQLæ°æ®åºçèåæå 个驱å¨å ç´ ï¼å
¶ä¸å
æ¬ï¼
* éè¦æ¯å
³ç³»æ°æ®åºæ´å¥½çå¯ä¼¸ç¼©æ§ï¼å
æ¬é常大çæ°æ®éæé常é«çåå
¥ååé
* ç¸æ¯åä¸æ°æ®åºäº§åï¼å
è´¹åå¼æºè½¯ä»¶æ´ååç±ã
* å
³ç³»æ¨¡åä¸è½å¾å¥½å°æ¯æä¸äºç¹æ®çæ¥è¯¢æä½
* åæ«äºå
³ç³»æ¨¡åçéå¶æ§ï¼æ¸´æä¸ç§æ´å
·å¤å¨ææ§ä¸è¡¨ç°åçæ°æ®æ¨¡åã5ã
ä¸åçåºç¨ç¨åºæä¸åçéæ±ï¼ä¸ä¸ªç¨ä¾çæä½³ææ¯éæ©å¯è½ä¸åäºå¦ä¸ä¸ªç¨ä¾çæä½³ææ¯éæ©ãå æ¤ï¼å¨å¯é¢è§çæªæ¥ï¼å
³ç³»æ°æ®åºä¼¼ä¹å¯è½ä¼ç»§ç»ä¸åç§éå
³ç³»æ°æ®åºä¸èµ·ä½¿ç¨ - è¿ç§æ³æ³ææ¶ä¹è¢«ç§°ä¸º**æ··åæä¹
åï¼polyglot persistenceï¼**ã
### 对象å
³ç³»ä¸å¹é
ç®å大å¤æ°åºç¨ç¨åºå¼åé½ä½¿ç¨é¢å对象çç¼ç¨è¯è¨æ¥å¼åï¼è¿å¯¼è´äºå¯¹SQLæ°æ®æ¨¡åçæ®éæ¹è¯ï¼å¦ææ°æ®åå¨å¨å
³ç³»è¡¨ä¸ï¼é£ä¹éè¦ä¸ä¸ªç¬¨æç转æ¢å±ï¼å¤äºåºç¨ç¨åºä»£ç ä¸ç对象å表ï¼è¡ï¼åçæ°æ®åºæ¨¡åä¹é´ã模åä¹é´çä¸è¿è´¯ææ¶è¢«ç§°ä¸º**é»æä¸å¹é
ï¼impedance mismatchï¼**[^i]ã
[^i]: ä¸ä¸ªä»çµåå¦åç¨çæ¯è¯ãæ¯ä¸ªçµè·¯çè¾å
¥åè¾åºé½æä¸å®çé»æï¼äº¤æµçµé»ï¼ãå½ä½ å°ä¸ä¸ªçµè·¯çè¾åºè¿æ¥å°å¦ä¸ä¸ªçµè·¯çè¾å
¥æ¶ï¼å¦æ两个çµè·¯çè¾åºåè¾å
¥é»æå¹é
ï¼åè¿æ¥ä¸çåçä¼ è¾å°è¢«æ大åãé»æä¸å¹é
ä¼å¯¼è´ä¿¡å·åå°åå
¶ä»é®é¢ã
åActiveRecordåHibernateè¿æ ·ç **对象å
³ç³»æ å°ï¼ORM object-relational mappingï¼** æ¡æ¶å¯ä»¥åå°è¿ä¸ªè½¬æ¢å±æéçæ ·æ¿ä»£ç çæ°éï¼ä½æ¯å®ä»¬ä¸è½å®å
¨éèè¿ä¸¤ä¸ªæ¨¡åä¹é´çå·®å¼ã
![](img/fig2-1.png)
**å¾2-1 使ç¨å
³ç³»å模å¼æ¥è¡¨ç¤ºé¢è±ç®ä»**
ä¾å¦ï¼[å¾2-1](img/fig2-1.png)å±ç¤ºäºå¦ä½å¨å
³ç³»æ¨¡å¼ä¸è¡¨ç¤ºç®åï¼ä¸ä¸ªLinkedInç®ä»ï¼ãæ´ä¸ªç®ä»å¯ä»¥éè¿ä¸ä¸ªå¯ä¸çæ è¯ç¬¦`user_id`æ¥æ è¯ãå`first_name`å`last_name`è¿æ ·çå段æ¯ä¸ªç¨æ·åªåºç°ä¸æ¬¡ï¼æ以å¯ä»¥å¨User表ä¸å°å
¶å»ºæ¨¡ä¸ºåãä½æ¯ï¼å¤§å¤æ°äººå¨èä¸ç涯ä¸æ¥æå¤äºä¸ä»½çå·¥ä½ï¼äººä»¬å¯è½æä¸åæ ·çæè²é¶æ®µåä»»ææ°éçè系信æ¯ãä»ç¨æ·å°è¿äºé¡¹ç®ä¹é´åå¨ä¸å¯¹å¤çå
³ç³»ï¼å¯ä»¥ç¨å¤ç§æ¹å¼æ¥è¡¨ç¤ºï¼
* ä¼ ç»SQL模åï¼SQLï¼1999ä¹åï¼ä¸ï¼æ常è§çè§èå表示形å¼æ¯å°èä½ï¼æè²åè系信æ¯æ¾å¨åç¬ç表ä¸ï¼å¯¹User表æä¾å¤é®å¼ç¨ï¼å¦[å¾2-1](img/fig2-1.png)æ示ã
* åç»çSQLæ åå¢å äºå¯¹ç»æåæ°æ®ç±»ååXMLæ°æ®çæ¯æ;è¿å
许å°å¤å¼æ°æ®åå¨å¨åè¡å
ï¼å¹¶æ¯æå¨è¿äºææ¡£å
æ¥è¯¢åç´¢å¼ãè¿äºåè½å¨Oracleï¼IBM DB2ï¼MS SQL ServeråPostgreSQLä¸é½æä¸åç¨åº¦çæ¯æã6,7ããJSONæ°æ®ç±»åä¹å¾å°å¤ä¸ªæ°æ®åºçæ¯æï¼å
æ¬IBM DB2ï¼MySQLåPostgreSQL ã8ãã
* 第ä¸ç§éæ©æ¯å°èä¸ï¼æè²åè系信æ¯ç¼ç 为JSONæXMLææ¡£ï¼å°å
¶åå¨å¨æ°æ®åºçææ¬åä¸ï¼å¹¶è®©åºç¨ç¨åºè§£æå
¶ç»æåå
容ãè¿ç§é
ç½®ä¸ï¼é常ä¸è½ä½¿ç¨æ°æ®åºæ¥æ¥è¯¢è¯¥ç¼ç åä¸çå¼ã
对äºä¸ä¸ªåç®åè¿æ ·èªå
å«ææ¡£çæ°æ®ç»æèè¨ï¼JSON表示æ¯é常åéçï¼åè§[ä¾2-1]()ãJSONæ¯XMLæ´ç®åãé¢åææ¡£çæ°æ®åºï¼å¦MongoDB ã9ãï¼RethinkDB ã10ãï¼CouchDB ã11ãåEspressoã12ãï¼æ¯æè¿ç§æ°æ®æ¨¡åã
**ä¾2-1. ç¨JSONæ档表示ä¸ä¸ªLinkedInç®ä»**
```json
{
"user_id": 251,
"first_name": "Bill",
"last_name": "Gates",
"summary": "Co-chair of the Bill & Melinda Gates... Active blogger.",
"region_id": "us:91",
"industry_id": 131,
"photo_url": "/p/7/000/253/05b/308dd6e.jpg",
"positions": [
{
"job_title": "Co-chair",
"organization": "Bill & Melinda Gates Foundation"
},
{
"job_title": "Co-founder, Chairman",
"organization": "Microsoft"
}
],
"education": [
{
"school_name": "Harvard University",
"start": 1973,
"end": 1975
},
{
"school_name": "Lakeside School, Seattle",
"start": null,
"end": null
}
],
"contact_info": {
"blog": "http://thegatesnotes.com",
"twitter": "http://twitter.com/BillGates"
}
}
```
æä¸äºå¼å人å认为JSON模ååå°äºåºç¨ç¨åºä»£ç ååå¨å±ä¹é´çé»æä¸å¹é
ãä¸è¿ï¼æ£å¦æ们å°å¨[第4ç« ](ch4.md)ä¸çå°çé£æ ·ï¼JSONä½ä¸ºæ°æ®ç¼ç æ ¼å¼ä¹åå¨é®é¢ã缺ä¹ä¸ä¸ªæ¨¡å¼å¾å¾è¢«è®¤ä¸ºæ¯ä¸ä¸ªä¼å¿;æ们å°å¨â[æ档模åä¸ç模å¼çµæ´»æ§](#æ档模åä¸ç模å¼çµæ´»æ§)âä¸è®¨è®ºè¿ä¸ªé®é¢ã
JSON表示æ¯[å¾2-1](img/fig2-1.png)ä¸çå¤è¡¨æ¨¡å¼å
·ææ´å¥½ç**å±é¨æ§ï¼localityï¼**ãå¦æå¨åé¢çå
³ç³»å示ä¾ä¸è·åç®ä»ï¼é£éè¦æ§è¡å¤ä¸ªæ¥è¯¢ï¼éè¿`user_id`æ¥è¯¢æ¯ä¸ªè¡¨ï¼ï¼æè
å¨User表ä¸å
¶ä¸å±è¡¨ä¹é´æ··ä¹±å°æ§è¡å¤è·¯è¿æ¥ãèå¨JSON表示ä¸ï¼ææç¸å
³ä¿¡æ¯é½å¨åä¸ä¸ªå°æ¹ï¼ä¸ä¸ªæ¥è¯¢å°±è¶³å¤äºã
ä»ç¨æ·ç®ä»æ件å°ç¨æ·èä½ï¼æè²åå²åè系信æ¯ï¼è¿ç§ä¸å¯¹å¤å
³ç³»éå«äºæ°æ®ä¸çä¸ä¸ªæ ç¶ç»æï¼èJSON表示使å¾è¿ä¸ªæ ç¶ç»æåå¾æç¡®ï¼è§[å¾2-2](img/fig2-2.png)ï¼ã
![](img/fig2-2.png)
**å¾2-2 ä¸å¯¹å¤å
³ç³»æ建äºä¸ä¸ªæ ç»æ**
### å¤å¯¹ä¸åå¤å¯¹å¤çå
³ç³»
å¨ä¸ä¸èç[ä¾2-1]()ä¸ï¼`region_id`å`industry_id`æ¯ä»¥IDï¼èä¸æ¯çº¯å符串âGreater Seattle AreaâåâPhilanthropyâçå½¢å¼ç»åºçã为ä»ä¹ï¼
å¦æç¨æ·çé¢ç¨ä¸ä¸ªèªç±ææ¬å段æ¥è¾å
¥åºååè¡ä¸ï¼é£ä¹å°ä»ä»¬åå¨ä¸ºçº¯ææ¬å符串æ¯åççãå¦ä¸æ¹å¼æ¯ç»åºå°çåºååè¡ä¸çæ ååçå表ï¼å¹¶è®©ç¨æ·ä»ä¸æå表æèªå¨å¡«å
å¨ä¸è¿è¡éæ©ï¼å
¶ä¼å¿å¦ä¸ï¼
* å个ç®ä»ä¹é´æ ·å¼åæ¼åç»ä¸
* é¿å
æ§ä¹ï¼ä¾å¦ï¼å¦ææå 个ååçåå¸ï¼
* æäºæ´æ°ââå称åªåå¨å¨ä¸ä¸ªå°æ¹ï¼å¦æéè¦æ´æ¹ï¼ä¾å¦ï¼ç±äºæ¿æ²»äºä»¶èæ¹ååå¸å称ï¼ï¼å¾å®¹æè¿è¡å
¨é¢æ´æ°ã
* æ¬å°åæ¯æââå½ç½ç«ç¿»è¯æå
¶ä»è¯è¨æ¶ï¼æ ååçå表å¯ä»¥è¢«æ¬å°åï¼ä½¿å¾å°åºåè¡ä¸å¯ä»¥ä½¿ç¨ç¨æ·çè¯è¨æ¥æ¾ç¤º
* æ´å¥½çæç´¢ââä¾å¦ï¼æç´¢åçé¡¿å·çæ
å家就ä¼å¹é
è¿ä»½ç®ä»ï¼å 为å°åºå表å¯ä»¥ç¼ç è®°å½è¥¿é
å¾å¨åçé¡¿è¿ä¸äºå®ï¼ä»âGreater Seattle Areaâè¿ä¸ªå符串ä¸çä¸åºæ¥ï¼
åå¨IDè¿æ¯ææ¬å符串ï¼è¿æ¯ä¸ª **å¯æ¬ï¼duplicationï¼** é®é¢ãå½ä½¿ç¨IDæ¶ï¼å¯¹äººç±»ææä¹çä¿¡æ¯ï¼æ¯å¦åè¯ï¼Philanthropyï¼åªåå¨å¨ä¸å¤ï¼ææå¼ç¨å®çå°æ¹ä½¿ç¨IDï¼IDåªå¨æ°æ®åºä¸ææä¹ï¼ãå½ç´æ¥åå¨ææ¬æ¶ï¼å¯¹äººç±»ææä¹çä¿¡æ¯ä¼å¤å¶å¨æ¯å¤ä½¿ç¨è®°å½ä¸ã
使ç¨IDç好å¤æ¯ï¼ID对人类没æä»»ä½æä¹ï¼å èæ°¸è¿ä¸éè¦æ¹åï¼IDå¯ä»¥ä¿æä¸åï¼å³ä½¿å®æ è¯çä¿¡æ¯åçååãä»»ä½å¯¹äººç±»ææä¹çä¸è¥¿é½å¯è½éè¦å¨å°æ¥æ个æ¶åæ¹åââå¦æè¿äºä¿¡æ¯è¢«å¤å¶ï¼ææçåä½å¯æ¬é½éè¦æ´æ°ãè¿ä¼å¯¼è´åå
¥å¼éï¼ä¹åå¨ä¸ä¸è´çé£é©ï¼ä¸äºå¯æ¬è¢«æ´æ°äºï¼è¿æäºå¯æ¬æ²¡æ被æ´æ°ï¼ãå»é¤æ¤ç±»éå¤æ¯æ°æ®åº **è§èåï¼normalizationï¼** çå
³é®ææ³ã[^ii]
[^ii]: å
³äºå
³ç³»æ¨¡åçæç®åºåäºå ç§ä¸åçè§èå½¢å¼ï¼ä½è¿äºåºå«å ä¹æ²¡æå®é
æä¹ãä¸ä¸ªç»éªæ³åæ¯ï¼å¦æéå¤åå¨äºå¯ä»¥åå¨å¨ä¸ä¸ªå°æ¹çå¼ï¼å模å¼å°±ä¸æ¯**è§èåï¼normalizedï¼**çã
> æ°æ®åºç®¡çååå¼å人åå欢äºè®ºè§èååéè§èåï¼è®©æ们ææ¶ä¿çå¤æå§ãå¨æ¬ä¹¦ç[第ä¸é¨å](part-iii.md)ï¼æ们å°åå°è¿ä¸ªè¯é¢ï¼æ¢è®¨ç³»ç»çæ¹æ³ç¨ä»¥å¤çç¼åï¼éè§èååè¡çæ°æ®ã
ä¸å¹¸çæ¯ï¼å¯¹è¿äºæ°æ®è¿è¡è§èåéè¦å¤å¯¹ä¸çå
³ç³»ï¼è®¸å¤äººçæ´»å¨ä¸ä¸ªç¹å®çå°åºï¼è®¸å¤äººå¨ä¸ä¸ªç¹å®çè¡ä¸å·¥ä½ï¼ï¼è¿ä¸æ档模åä¸å¤ªå»åãå¨å
³ç³»æ°æ®åºä¸ï¼éè¿IDæ¥å¼ç¨å
¶ä»è¡¨ä¸çè¡æ¯æ£å¸¸çï¼å 为è¿æ¥å¾å®¹æãå¨ææ¡£æ°æ®åºä¸ï¼ä¸å¯¹å¤æ ç»æ没æå¿
è¦ç¨è¿æ¥ï¼å¯¹è¿æ¥çæ¯æé常å¾å¼±[^iii]ã
[^iii]: å¨æ°åæ¬ææ¶ï¼RethinkDBæ¯æè¿æ¥ï¼MongoDBä¸æ¯æè¿æ¥ï¼èCouchDBåªæ¯æé¢å
声æçè§å¾ã
å¦ææ°æ®åºæ¬èº«ä¸æ¯æè¿æ¥ï¼åå¿
é¡»å¨åºç¨ç¨åºä»£ç ä¸éè¿å¯¹æ°æ®åºè¿è¡å¤ä¸ªæ¥è¯¢æ¥æ¨¡æè¿æ¥ãï¼å¨è¿ç§æ
åµä¸ï¼å°åºåè¡ä¸çå表å¯è½å¾å°ï¼æ¹å¨å¾å°ï¼åºç¨ç¨åºå¯ä»¥ç®åå°å°å
¶ä¿åå¨å
åä¸ãä¸è¿ï¼æ§è¡è¿æ¥çå·¥ä½ä»æ°æ®åºè¢«è½¬ç§»å°åºç¨ç¨åºä»£ç ä¸ã
æ¤å¤ï¼å³ä¾¿åºç¨ç¨åºçæåçæ¬éåæ è¿æ¥çæ档模åï¼éçåè½æ·»å å°åºç¨ç¨åºä¸ï¼æ°æ®ä¼åå¾æ´å äºèãä¾å¦ï¼èèä¸ä¸å¯¹ç®åä¾åè¿è¡çä¸äºä¿®æ¹ï¼
***ç»ç»åå¦æ ¡ä½ä¸ºå®ä½***
å¨åé¢çæè¿°ä¸ï¼`organization`ï¼ç¨æ·å·¥ä½çå
¬å¸ï¼å`school_name`ï¼ä»ä»¬å¦ä¹ çå°æ¹ï¼åªæ¯å符串ãä¹è®¸ä»ä»¬åºè¯¥æ¯å¯¹å®ä½çå¼ç¨å¢ï¼ç¶åï¼æ¯ä¸ªç»ç»ï¼å¦æ ¡æ大å¦é½å¯ä»¥æ¥æèªå·±çç½é¡µï¼æ è¯ï¼æ°é»æè¦çï¼ãæ¯ä¸ªç®åå¯ä»¥é¾æ¥å°å®ææå°çç»ç»åå¦æ ¡ï¼å¹¶ä¸å
æ¬ä»ä»¬çå¾æ åå
¶ä»ä¿¡æ¯ï¼åè§[å¾2-3](img/fig2-3.png)ï¼æ¥èªLinkedInçä¸ä¸ªä¾åï¼ã
***æ¨è***
åè®¾ä½ æ³æ·»å ä¸ä¸ªæ°çåè½ï¼ä¸ä¸ªç¨æ·å¯ä»¥ä¸ºå¦ä¸ä¸ªç¨æ·åä¸ä¸ªæ¨èãå¨ç¨æ·çç®åä¸æ¾ç¤ºæ¨èï¼å¹¶éä¸æ¨èç¨æ·çå§ååç
§çãå¦ææ¨è人æ´æ°ä»ä»¬çç
§çï¼é£ä»ä»¬åçä»»ä½å»ºè®®é½éè¦æ¾ç¤ºæ°çç
§çãå æ¤ï¼æ¨èåºè¯¥æ¥æä½è
个人ç®ä»çå¼ç¨ã
![](img/fig2-3.png)
**å¾2-3 å
¬å¸åä¸ä»
æ¯å符串ï¼è¿æ¯ä¸ä¸ªæåå
¬å¸å®ä½çé¾æ¥ï¼LinkedInæªå¾ï¼**
[å¾2-4](img/fig2-4.png)éæäºè¿äºæ°åè½éè¦å¦ä½ä½¿ç¨å¤å¯¹å¤å
³ç³»ãæ¯ä¸ªè线ç©å½¢å
çæ°æ®å¯ä»¥åç»æä¸ä¸ªææ¡£ï¼ä½æ¯å¯¹åä½ï¼å¦æ ¡åå
¶ä»ç¨æ·çå¼ç¨éè¦è¡¨ç¤ºæå¼ç¨ï¼å¹¶ä¸å¨æ¥è¯¢æ¶éè¦è¿æ¥ã
![](img/fig2-4.png)
**å¾2-4 使ç¨å¤å¯¹å¤å
³ç³»æ©å±ç®å**
### ææ¡£æ°æ®åºæ¯å¦å¨éè¹è¦è¾ï¼
å¨å¤å¯¹å¤çå
³ç³»åè¿æ¥å·²å¸¸è§ç¨å¨å
³ç³»æ°æ®åºæ¶ï¼ææ¡£æ°æ®åºåNoSQLéå¯äºè¾©è®ºï¼å¦ä½æ好å°å¨æ°æ®åºä¸è¡¨ç¤ºå¤å¯¹å¤å
³ç³»ãé£åºè¾©è®ºå¯æ¯NoSQLå¤èå¾å¤ï¼äºå®ä¸ï¼ææ©å¯ä»¥è¿½æº¯å°è®¡ç®æºåæ°æ®åºç³»ç»ã
20ä¸çºª70年代æå欢è¿çä¸å¡æ°æ®å¤çæ°æ®åºæ¯IBMçä¿¡æ¯ç®¡çç³»ç»ï¼IMSï¼ï¼æåæ¯ä¸ºäºé¿æ³¢ç½å¤ªç©ºè®¡åçåºå管çèå¼åçï¼å¹¶äº1968å¹´æäºé¦æ¬¡åä¸åå¸ã13ããç®åå®ä»å¨ä½¿ç¨åç»´æ¤ï¼è¿è¡å¨IBM大åæºçOS/390ä¸ã14ãã
IMSç设计ä¸ä½¿ç¨äºä¸ä¸ªç¸å½ç®åçæ°æ®æ¨¡åï¼ç§°ä¸º**å±æ¬¡æ¨¡åï¼hierarchical modelï¼**ï¼å®ä¸ææ¡£æ°æ®åºä½¿ç¨çJSON模åæä¸äºæ人çç¸ä¼¼ä¹å¤ã2ããå®å°æææ°æ®è¡¨ç¤ºä¸ºåµå¥å¨è®°å½ä¸çè®°å½æ ï¼è¿å¾å[å¾2-2](img/fig2-2.png)çJSONç»æã
åææ¡£æ°æ®åºä¸æ ·ï¼IMSè½è¯å¥½å¤çä¸å¯¹å¤çå
³ç³»ï¼ä½æ¯å¾é¾åºå¯¹å¤å¯¹å¤çå
³ç³»ï¼å¹¶ä¸ä¸æ¯æè¿æ¥ãå¼å人åå¿
é¡»å³å®æ¯å¦å¤å¶ï¼éè§èåï¼æ°æ®ææå¨è§£å³ä»ä¸ä¸ªè®°å½å°å¦ä¸ä¸ªè®°å½çå¼ç¨ãè¿äºäºåä¸çºªå
ä¸å年代çé®é¢ä¸ç°å¨å¼å人åéå°çææ¡£æ°æ®åºé®é¢é常ç¸ä¼¼ã15ãã
é£æ¶äººä»¬æåºäºåç§ä¸åç解å³æ¹æ¡æ¥è§£å³å±æ¬¡æ¨¡åçå±éæ§ãå
¶ä¸æçªåºç两个æ¯**å
³ç³»æ¨¡åï¼relational modelï¼**ï¼å®åæäºSQLï¼ç»æ²»äºä¸çï¼å**ç½ç»æ¨¡åï¼network modelï¼**ï¼æåå¾åå
³æ³¨ï¼ä½æç»åå¾å·é¨ï¼ãè¿ä¸¤ä¸ªéµè¥ä¹é´çâ大辩论âå¨70年代æç»äºå¾ä¹
æ¶é´ã2ãã
é£ä¸¤ä¸ªæ¨¡å¼è§£å³çé®é¢ä¸å½åçé®é¢ç¸å
³ï¼å æ¤å¼å¾ç®è¦å顾ä¸ä¸é£åºè¾©è®ºã
#### ç½ç»æ¨¡å
ç½ç»æ¨¡åç±ä¸ä¸ªç§°ä¸ºæ°æ®ç³»ç»è¯è¨ä¼è®®ï¼CODASYLï¼çå§åä¼è¿è¡äºæ ååï¼å¹¶è¢«æ°ä¸ªä¸åçæ°æ®åºåå®ç°;å®ä¹è¢«ç§°ä¸ºCODASYL模åã16ãã
CODASYL模åæ¯å±æ¬¡æ¨¡åçæ¨å¹¿ãå¨å±æ¬¡æ¨¡åçæ ç»æä¸ï¼æ¯æ¡è®°å½åªæä¸ä¸ªç¶èç¹ï¼å¨ç½ç»æ¨¡å¼ä¸ï¼æ¯æ¡è®°å½å¯è½æå¤ä¸ªç¶èç¹ãä¾å¦ï¼âGreater Seattle Areaâå°åºå¯è½æ¯ä¸æ¡è®°å½ï¼æ¯ä¸ªå±
ä½å¨è¯¥å°åºçç¨æ·é½å¯ä»¥ä¸ä¹ç¸å
³èãè¿å
许对å¤å¯¹ä¸åå¤å¯¹å¤çå
³ç³»è¿è¡å»ºæ¨¡ã
ç½ç»æ¨¡åä¸è®°å½ä¹é´çé¾æ¥ä¸æ¯å¤é®ï¼èæ´åç¼ç¨è¯è¨ä¸çæéï¼åæ¶ä»ç¶åå¨å¨ç£çä¸ï¼ã访é®è®°å½çå¯ä¸æ¹æ³æ¯è·éä»æ ¹è®°å½èµ·æ²¿è¿äºé¾è·¯æå½¢æçè·¯å¾ãè¿è¢«ç§°ä¸º**访é®è·¯å¾ï¼access pathï¼**ã
æç®åçæ
åµä¸ï¼è®¿é®è·¯å¾ç±»ä¼¼éåé¾è¡¨ï¼ä»å表头å¼å§ï¼æ¯æ¬¡æ¥çä¸æ¡è®°å½ï¼ç´å°æ¾å°æéçè®°å½ãä½å¨å¤å¯¹å¤å
³ç³»çæ
åµä¸ï¼æ°æ¡ä¸åçè·¯å¾å¯ä»¥å°è¾¾ç¸åçè®°å½ï¼ç½ç»æ¨¡åçç¨åºåå¿
é¡»è·è¸ªè¿äºä¸åç访é®è·¯å¾ã
CODASYLä¸çæ¥è¯¢æ¯éè¿å©ç¨éåè®°å½ååè·é访é®è·¯å¾è¡¨å¨æ°æ®åºä¸ç§»å¨æ¸¸æ æ¥æ§è¡çãå¦æè®°å½æå¤ä¸ªç¶ç»ç¹ï¼å³å¤ä¸ªæ¥èªå
¶ä»è®°å½çä¼ å
¥æéï¼ï¼ååºç¨ç¨åºä»£ç å¿
é¡»è·è¸ªææçåç§å
³ç³»ãçè³CODASYLå§åä¼æåä¹æ¿è®¤ï¼è¿å°±åå¨nç»´æ°æ®ç©ºé´ä¸è¿è¡å¯¼èªã17ãã
尽管æå¨éæ©è®¿é®è·¯å¾å¤è½æææå°å©ç¨20ä¸çºª70年代é常æéç硬件åè½ï¼å¦ç£å¸¦é©±å¨å¨ï¼å
¶æç´¢é度é常æ
¢ï¼ï¼ä½è¿ä½¿å¾æ¥è¯¢åæ´æ°æ°æ®åºç代ç åå¾å¤æä¸çµæ´»ãæ 论æ¯åå±è¿æ¯ç½ç»æ¨¡åï¼å¦æä½ æ²¡ææéæ°æ®çè·¯å¾ï¼å°±ä¼é·å
¥å°å¢ãä½ å¯ä»¥æ¹å访é®è·¯å¾ï¼ä½æ¯å¿
é¡»æµè§å¤§éæåæ°æ®åºæ¥è¯¢ä»£ç ï¼å¹¶éåæ¥å¤çæ°ç访é®è·¯å¾ãæ´æ¹åºç¨ç¨åºçæ°æ®æ¨¡åæ¯å¾é¾çã
#### å
³ç³»æ¨¡å
ç¸æ¯ä¹ä¸ï¼å
³ç³»æ¨¡ååçå°±æ¯å°ææçæ°æ®æ¾å¨å
天åæ¥ä¹ä¸ï¼ä¸ä¸ª **å
³ç³»ï¼è¡¨ï¼** åªæ¯ä¸ä¸ª **å
ç»ï¼è¡ï¼** çéåï¼ä»
æ¤èå·²ãå¦æä½ æ³è¯»åæ°æ®ï¼å®æ²¡æ迷宫似çåµå¥ç»æï¼ä¹æ²¡æå¤æç访é®è·¯å¾ãä½ å¯ä»¥éä¸ç¬¦åä»»ææ¡ä»¶çè¡ï¼è¯»å表ä¸çä»»ä½æææè¡ãä½ å¯ä»¥éè¿æå®æäºåä½ä¸ºå¹é
å
³é®åæ¥è¯»åç¹å®è¡ãä½ å¯ä»¥å¨ä»»ä½è¡¨ä¸æå
¥ä¸ä¸ªæ°çè¡ï¼èä¸å¿
æ
å¿ä¸å
¶ä»è¡¨çå¤é®å
³ç³»[^iv]ã
[^iv]: å¤é®çº¦æå
许对修æ¹çº¦æï¼ä½å¯¹äºå
³ç³»æ¨¡åè¿å¹¶ä¸æ¯å¿
é项ãå³ä½¿æ约æï¼å¤é®è¿æ¥å¨æ¥è¯¢æ¶æ§è¡ï¼èå¨CODASYLä¸ï¼è¿æ¥å¨æå
¥æ¶é«æå®æã
å¨å
³ç³»æ°æ®åºä¸ï¼æ¥è¯¢ä¼åå¨èªå¨å³å®æ¥è¯¢çåªäºé¨å以åªä¸ªé¡ºåºæ§è¡ï¼ä»¥å使ç¨åªäºç´¢å¼ãè¿äºéæ©å®é
ä¸æ¯â访é®è·¯å¾âï¼ä½æ大çåºå«å¨äºå®ä»¬æ¯ç±æ¥è¯¢ä¼åå¨èªå¨çæçï¼èä¸æ¯ç±ç¨åºåçæï¼æ以æ们å¾å°éè¦èèå®ä»¬ã
å¦ææ³ææ°çæ¹å¼æ¥è¯¢æ°æ®ï¼ä½ å¯ä»¥å£°æä¸ä¸ªæ°çç´¢å¼ï¼æ¥è¯¢ä¼èªå¨ä½¿ç¨æåéçé£äºç´¢å¼ãæ éæ´æ¹æ¥è¯¢æ¥å©ç¨æ°çç´¢å¼ãï¼è¯·åé
â[ç¨äºæ°æ®çæ¥è¯¢è¯è¨](#ç¨äºæ°æ®çæ¥è¯¢è¯è¨)âãï¼å
³ç³»æ¨¡åå æ¤ä½¿æ·»å åºç¨ç¨åºæ°åè½åå¾æ´å 容æã
å
³ç³»æ°æ®åºçæ¥è¯¢ä¼åå¨æ¯å¤æçï¼å·²èè´¹äºå¤å¹´çç 究åå¼åç²¾åã18ããå
³ç³»æ¨¡åçä¸ä¸ªå
³é®æ´å¯æ¯ï¼åªéæ建ä¸æ¬¡æ¥è¯¢ä¼åå¨ï¼éå使ç¨è¯¥æ°æ®åºçææåºç¨ç¨åºé½å¯ä»¥ä»ä¸åçãå¦æä½ æ²¡ææ¥è¯¢ä¼åå¨çè¯ï¼é£ä¹ä¸ºç¹å®æ¥è¯¢æå¨ç¼å访é®è·¯å¾æ¯ç¼åéç¨ä¼åå¨æ´å®¹æââä¸è¿ä»é¿æçéç¨è§£å³æ¹æ¡æ´å¥½ã
#### ä¸ææ¡£æ°æ®åºç¸æ¯
å¨ä¸ä¸ªæ¹é¢ï¼ææ¡£æ°æ®åºè¿å为å±æ¬¡æ¨¡åï¼å¨å
¶ç¶è®°å½ä¸åå¨åµå¥è®°å½ï¼[å¾2-1]()ä¸çä¸å¯¹å¤å
³ç³»ï¼å¦`positions`ï¼`education`å`contact_info`ï¼ï¼èä¸æ¯å¨åç¬ç表ä¸ã
ä½æ¯ï¼å¨è¡¨ç¤ºå¤å¯¹ä¸åå¤å¯¹å¤çå
³ç³»æ¶ï¼å
³ç³»æ°æ®åºåææ¡£æ°æ®åºå¹¶æ²¡ææ ¹æ¬çä¸åï¼å¨è¿ä¸¤ç§æ
åµä¸ï¼ç¸å
³é¡¹ç®é½è¢«ä¸ä¸ªå¯ä¸çæ è¯ç¬¦å¼ç¨ï¼è¿ä¸ªæ è¯ç¬¦å¨å
³ç³»æ¨¡åä¸è¢«ç§°ä¸º**å¤é®**ï¼å¨æ档模åä¸ç§°ä¸º**ææ¡£å¼ç¨**ã9ãã该æ è¯ç¬¦å¨è¯»åæ¶éè¿è¿æ¥æåç»æ¥è¯¢æ¥è§£æãè¿ä»ä¸ºæ¢ï¼ææ¡£æ°æ®åºæ²¡æèµ°CODASYLçèè·¯ã
### å
³ç³»åæ°æ®åºä¸ææ¡£æ°æ®åºå¨ä»æ¥ç对æ¯
å°å
³ç³»æ°æ®åºä¸ææ¡£æ°æ®åºè¿è¡æ¯è¾æ¶ï¼å¯ä»¥èè许å¤æ¹é¢çå·®å¼ï¼å
æ¬å®ä»¬ç容éå±æ§ï¼åé
[第5ç« ](ch5.md)ï¼åå¤ç并åæ§ï¼åé
[第7ç« ](ch7.md)ï¼ãæ¬ç« å°åªå
³æ³¨æ°æ®æ¨¡åä¸çå·®å¼ã
æ¯æææ¡£æ°æ®æ¨¡åç主è¦è®ºæ®æ¯æ¶æçµæ´»æ§ï¼å å±é¨æ§èæ¥ææ´å¥½çæ§è½ï¼ä»¥å对äºæäºåºç¨ç¨åºèè¨æ´æ¥è¿äºåºç¨ç¨åºä½¿ç¨çæ°æ®ç»æãå
³ç³»æ¨¡åéè¿ä¸ºè¿æ¥æä¾æ´å¥½çæ¯æ以åæ¯æå¤å¯¹ä¸åå¤å¯¹å¤çå
³ç³»æ¥åå»ã
#### åªç§æ°æ®æ¨¡åæ´æå©äºç®ååºç¨ä»£ç ï¼
å¦æåºç¨ç¨åºä¸çæ°æ®å
·æ类似ææ¡£çç»æï¼å³ï¼ä¸å¯¹å¤å
³ç³»æ ï¼é常ä¸æ¬¡æ§å è½½æ´ä¸ªæ ï¼ï¼é£ä¹ä½¿ç¨æ档模åå¯è½æ¯ä¸ä¸ªå¥½ä¸»æãå°ç±»ä¼¼ææ¡£çç»æå解æå¤ä¸ªè¡¨ï¼å¦[å¾2-1](img/fig2-1.png)ä¸ç`positions`ï¼`education`å`contact_info`ï¼çå
³ç³»ææ¯å¯è½å¯¼è´ç¹çç模å¼åä¸å¿
è¦çå¤æçåºç¨ç¨åºä»£ç ã
æ档模åæä¸å®çå±éæ§ï¼ä¾å¦ï¼ä¸è½ç´æ¥å¼ç¨ææ¡£ä¸çåµå¥ç项ç®ï¼èæ¯éè¦è¯´âç¨æ·251çä½ç½®å表ä¸ç第äºé¡¹âï¼å¾ååå±æ¨¡åä¸ç访é®è·¯å¾ï¼ãä½æ¯ï¼åªè¦æ件åµå¥ä¸å¤ªæ·±ï¼è¿é常ä¸æ¯é®é¢ã
ææ¡£æ°æ®åºå¯¹è¿æ¥çç³ç³æ¯æå¯è½æ¯ä¸ªé®é¢ï¼ä¹å¯è½ä¸æ¯é®é¢ï¼è¿åå³äºåºç¨ç¨åºãä¾å¦ï¼å¦ææåæååºç¨ç¨åºä½¿ç¨ä¸ä¸ªææ¡£æ°æ®åºæ¥è®°å½ä½æ¶ä½å°åçäºä½äºï¼é£ä¹å¤å¯¹å¤å
³ç³»å¯è½æ°¸è¿ä¹ç¨ä¸ä¸ãã19ãã
ä½å¦æä½ çåºç¨ç¨åºç¡®å®ä¼ç¨å°å¤å¯¹å¤å
³ç³»ï¼é£ä¹æ档模å就没æé£ä¹è¯±äººäºã尽管å¯ä»¥éè¿åè§èåæ¥æ¶é¤å¯¹è¿æ¥çéæ±ï¼ä½è¿éè¦åºç¨ç¨åºä»£ç æ¥åé¢å¤çå·¥ä½ä»¥ç¡®ä¿æ°æ®ä¸è´æ§ã尽管åºç¨ç¨åºä»£ç å¯ä»¥éè¿åæ°æ®åºååºå¤ä¸ªè¯·æ±çæ¹å¼æ¥æ¨¡æè¿æ¥ï¼ä½è¿ä¹å°å¤ææ§è½¬ç§»å°åºç¨ç¨åºä¸ï¼èä¸é常ä¹ä¼æ¯ç±æ°æ®åºå
çä¸ç¨ä»£ç æ´æ
¢ãå¨è¿ç§æ
åµä¸ï¼ä½¿ç¨æ档模åå¯è½ä¼å¯¼è´æ´å¤æçåºç¨ä»£ç ä¸æ´å·®çæ§è½ã15ãã
æ们没æåæ³è¯´åªç§æ°æ®æ¨¡åæ´æå©äºç®ååºç¨ä»£ç ï¼å 为å®åå³äºæ°æ®é¡¹ä¹é´çå
³ç³»ç§ç±»ã对é«åº¦å
³èçæ°æ®èè¨ï¼æ档模åæ¯æå
¶ç³ç³çï¼å
³ç³»æ¨¡åæ¯å¯ä»¥æ¥åçï¼èéç¨å¾å½¢æ¨¡åï¼åè§â[å¾æ°æ®æ¨¡å](#å¾æ°æ®æ¨¡å)âï¼æ¯æèªç¶çã
#### æ档模åä¸çæ¶æçµæ´»æ§
大å¤æ°ææ¡£æ°æ®åºä»¥åå
³ç³»æ°æ®åºä¸çJSONæ¯æé½ä¸ä¼å¼ºå¶ææ¡£ä¸çæ°æ®éç¨ä½ç§æ¨¡å¼ãå
³ç³»æ°æ®åºçXMLæ¯æé常带æå¯éç模å¼éªè¯ã没æ模å¼æå³çå¯ä»¥å°ä»»æçé®åå¼æ·»å å°ææ¡£ä¸ï¼å¹¶ä¸å½è¯»åæ¶ï¼å®¢æ·ç«¯å¯¹æ æ³ä¿è¯ææ¡£å¯è½å
å«çå段ã
ææ¡£æ°æ®åºææ¶ç§°ä¸º**æ 模å¼ï¼schemalessï¼**ï¼ä½è¿å
·æ误导æ§ï¼å 为读åæ°æ®ç代ç é常åå®æç§ç»æââå³åå¨éå¼æ¨¡å¼ï¼ä½ä¸ç±æ°æ®åºå¼ºå¶æ§è¡ã20ããä¸ä¸ªæ´ç²¾ç¡®çæ¯è¯æ¯**读æ¶æ¨¡å¼ï¼schema-on-readï¼**ï¼æ°æ®çç»ææ¯éå«çï¼åªæå¨æ°æ®è¢«è¯»åæ¶æ被解éï¼ï¼ç¸åºçæ¯**åæ¶æ¨¡å¼ï¼schema-on-writeï¼**ï¼ä¼ ç»çå
³ç³»æ°æ®åºæ¹æ³ä¸ï¼æ¨¡å¼æç¡®ï¼ä¸æ°æ®åºç¡®ä¿ææçæ°æ®é½ç¬¦åå
¶æ¨¡å¼ï¼ã21ãã
读æ¶æ¨¡å¼ç±»ä¼¼äºç¼ç¨è¯è¨ä¸çå¨æï¼è¿è¡æ¶ï¼ç±»åæ£æ¥ï¼èåæ¶æ¨¡å¼ç±»ä¼¼äºéæï¼ç¼è¯æ¶ï¼ç±»åæ£æ¥ãå°±åéæåå¨æç±»åæ£æ¥çç¸å¯¹ä¼ç¹å
·æå¾å¤§çäºè®®æ§ä¸æ ·ã22ãï¼æ°æ®åºä¸æ¨¡å¼ç强å¶æ§æ¯ä¸ä¸ªå
·æäºè®®çè¯é¢ï¼ä¸è¬æ¥è¯´æ²¡ææ£ç¡®æé误ççæ¡ã
å¨åºç¨ç¨åºæ³è¦æ¹åå
¶æ°æ®æ ¼å¼çæ
åµä¸ï¼è¿äºæ¹æ³ä¹é´çåºå«å°¤å
¶ææ¾ãä¾å¦ï¼åè®¾ä½ ææ¯ä¸ªç¨æ·çå
¨ååå¨å¨ä¸ä¸ªå段ä¸ï¼èç°å¨æ³åå«åå¨åååå§æ°ã23ããå¨ææ¡£æ°æ®åºä¸ï¼åªéå¼å§åå
¥å
·ææ°å段çæ°ææ¡£ï¼å¹¶å¨åºç¨ç¨åºä¸ä½¿ç¨ä»£ç æ¥å¤ç读åæ§ææ¡£çæ
åµãä¾å¦ï¼
```go
if (user && user.name && !user.first_name) {
// Documents written before Dec 8, 2013 don't have first_name
user.first_name = user.name.split(" ")[0];
}
```
å¦ä¸æ¹é¢ï¼å¨âéæç±»åâæ°æ®åºæ¨¡å¼ä¸ï¼é常ä¼æ§è¡ä»¥ä¸ **è¿ç§»ï¼migrationï¼** æä½ï¼
```sql
ALTER TABLE users ADD COLUMN first_name text;
UPDATE users SET first_name = split_part(name, ' ', 1); -- PostgreSQL
UPDATE users SET first_name = substring_index(name, ' ', 1); -- MySQL
```
模å¼åæ´çé度å¾æ
¢ï¼èä¸è¦æ±åè¿ãå®çè¿ç§ååèªå¹¶ä¸æ¯å®å
¨åºå¾çï¼å¤§å¤æ°å
³ç³»æ°æ®åºç³»ç»å¯å¨å 毫ç§å
æ§è¡`ALTER TABLE`è¯å¥ãMySQLæ¯ä¸ä¸ªå¼å¾æ³¨æçä¾å¤ï¼å®æ§è¡`ALTER TABLE`æ¶ä¼å¤å¶æ´ä¸ªè¡¨ï¼è¿å¯è½æå³çå¨æ´æ¹ä¸ä¸ªå¤§å表æ¶ä¼è±è´¹å åéçè³å 个å°æ¶çåæºæ¶é´ï¼å°½ç®¡åå¨åç§å·¥å
·æ¥è§£å³è¿ä¸ªéå¶ã24,25,26ãã
大å表ä¸è¿è¡`UPDATE`è¯å¥å¨ä»»ä½æ°æ®åºä¸é½å¯è½ä¼å¾æ
¢ï¼å 为æ¯ä¸è¡é½éè¦éåãè¦æ¯ä¸å¯æ¥åçè¯ï¼åºç¨ç¨åºå¯ä»¥å°`first_name`设置为é»è®¤å¼`NULL`ï¼å¹¶å¨è¯»åæ¶åå¡«å
ï¼å°±å使ç¨ææ¡£æ°æ®åºä¸æ ·ã
å½ç±äºæç§åå ï¼ä¾å¦ï¼æ°æ®æ¯å¼æçï¼éåä¸ç项ç®å¹¶ä¸é½å
·æç¸åçç»ææ¶,读æ¶æ¨¡å¼æ´å
·ä¼å¿ãä¾å¦ï¼å¦æï¼
* åå¨è®¸å¤ä¸åç±»åç对象ï¼å°æ¯ç§ç±»åç对象æ¾å¨èªå·±ç表ä¸æ¯ä¸ç°å®çã
* æ°æ®çç»æç±å¤é¨ç³»ç»å³å®ãä½ æ æ³æ§å¶å¤é¨ç³»ç»ä¸å®éæ¶å¯è½ååã
å¨ä¸è¿°æ
åµä¸ï¼æ¨¡å¼çåå¤è¿å¤§äºå®ç帮å©ï¼æ 模å¼ææ¡£å¯è½æ¯ä¸ä¸ªæ´å èªç¶çæ°æ®æ¨¡åãä½æ¯ï¼è¦æ¯ææè®°å½é½å
·æç¸åçç»æï¼é£ä¹æ¨¡å¼æ¯è®°å½å¹¶å¼ºå¶è¿ç§ç»æçæææºå¶ã第åç« å°æ´è¯¦ç»å°è®¨è®ºæ¨¡å¼å模å¼æ¼åã
#### æ¥è¯¢çæ°æ®å±é¨æ§
ææ¡£é常以å个è¿ç»å符串形å¼è¿è¡åå¨ï¼ç¼ç 为JSONï¼XMLæå
¶äºè¿å¶åä½ï¼å¦MongoDBçBSONï¼ãå¦æåºç¨ç¨åºç»å¸¸éè¦è®¿é®æ´ä¸ªææ¡£ï¼ä¾å¦ï¼å°å
¶æ¸²æè³ç½é¡µï¼ï¼é£ä¹åå¨å±é¨æ§ä¼å¸¦æ¥æ§è½ä¼å¿ãå¦æå°æ°æ®åå²å°å¤ä¸ªè¡¨ä¸ï¼å¦[å¾2-1](img/fig2-1.png)æ示ï¼ï¼åéè¦è¿è¡å¤æ¬¡ç´¢å¼æ¥æ¾æè½å°å
¶å
¨é¨æ£ç´¢åºæ¥ï¼è¿å¯è½éè¦æ´å¤çç£çæ¥æ¾å¹¶è±è´¹æ´å¤çæ¶é´ã
å±é¨æ§ä»
ä»
éç¨äºåæ¶éè¦ææ¡£ç»å¤§é¨åå
容çæ
åµãæ°æ®åºé常éè¦å è½½æ´ä¸ªææ¡£ï¼å³ä½¿åªè®¿é®å
¶ä¸çä¸å°é¨åï¼è¿å¯¹äºå¤§åææ¡£æ¥è¯´æ¯å¾æµªè´¹çãæ´æ°ææ¡£æ¶ï¼é常éè¦æ´ä¸ªéåãåªæä¸æ¹åæ档大å°çä¿®æ¹æå¯ä»¥å®¹æå°åå°æ§è¡ãå æ¤ï¼é常建议ä¿æç¸å¯¹å°çææ¡£ï¼å¹¶é¿å
å¢å æ档大å°çåå
¥ã9ããè¿äºæ§è½éå¶å¤§å¤§åå°äºææ¡£æ°æ®åºçå®ç¨åºæ¯ã
å¼å¾æåºçæ¯ï¼ä¸ºäºå±é¨æ§èåç»éåç¸å
³æ°æ®çæ³æ³å¹¶ä¸å±éäºæ档模åãä¾å¦ï¼GoogleçSpanneræ°æ®åºå¨å
³ç³»æ°æ®æ¨¡åä¸æä¾äºåæ ·çå±é¨æ§å±æ§ï¼å
许模å¼å£°æä¸ä¸ªè¡¨çè¡åºè¯¥äº¤éï¼åµå¥ï¼å¨ç¶è¡¨å
ã27ããOracle类似å°å
许使ç¨ä¸ä¸ªç§°ä¸º **å¤è¡¨ç´¢å¼é群表ï¼multi-table index cluster tablesï¼** ç类似ç¹æ§ã28ããBigtableæ°æ®æ¨¡åï¼ç¨äºCassandraåHBaseï¼ä¸ç **åæï¼column-familyï¼** æ¦å¿µä¸ç®¡çå±é¨æ§çç®ç类似ã29ãã
å¨[第3ç« ](ch3.md)å°è¿ä¼çå°æ´å¤å
³äºå±é¨æ§çå
容ã
#### ææ¡£åå
³ç³»æ°æ®åºçèå
èª2000年代ä¸æ以æ¥ï¼å¤§å¤æ°å
³ç³»æ°æ®åºç³»ç»ï¼MySQLé¤å¤ï¼é½å·²æ¯æXMLãè¿å
æ¬å¯¹XMLææ¡£è¿è¡æ¬å°ä¿®æ¹çåè½ï¼ä»¥åå¨XMLææ¡£ä¸è¿è¡ç´¢å¼åæ¥è¯¢çåè½ãè¿å
许åºç¨ç¨åºä½¿ç¨é£ç§ä¸ææ¡£æ°æ®åºåºå½ä½¿ç¨çé常类似çæ°æ®æ¨¡åã
ä»9.3çæ¬å¼å§çPostgreSQL ã8ãï¼ä»5.7çæ¬å¼å§çMySQL以åä»çæ¬10.5å¼å§çIBM DB2 [30]ä¹å¯¹JSONææ¡£æä¾äºç±»ä¼¼çæ¯æ级å«ãé´äºç¨å¨Web APIsçJSONæµè¡è¶å¿ï¼å
¶ä»å
³ç³»æ°æ®åºå¾å¯è½ä¼è·éä»ä»¬çèæ¥å¹¶æ·»å JSONæ¯æã
å¨ææ¡£æ°æ®åºä¸ï¼RethinkDBå¨å
¶æ¥è¯¢è¯è¨ä¸æ¯æ类似å
³ç³»çè¿æ¥ï¼ä¸äºMongoDB驱å¨ç¨åºå¯ä»¥èªå¨è§£ææ°æ®åºå¼ç¨ï¼ææå°æ§è¡å®¢æ·ç«¯è¿æ¥ï¼å°½ç®¡è¿å¯è½æ¯å¨æ°æ®åºä¸æ§è¡çè¿æ¥æ
¢ï¼éè¦é¢å¤çç½ç»å¾è¿ï¼å¹¶ä¸ä¼åæ´å°ï¼ã
éçæ¶é´çæ¨ç§»ï¼å
³ç³»æ°æ®åºåææ¡£æ°æ®åºä¼¼ä¹åå¾è¶æ¥è¶ç¸ä¼¼ï¼è¿æ¯ä¸ä»¶å¥½äºï¼æ°æ®æ¨¡åç¸äºè¡¥å
[^v]ï¼å¦æä¸ä¸ªæ°æ®åºè½å¤å¤ç类似ææ¡£çæ°æ®ï¼å¹¶è½å¤å¯¹å
¶æ§è¡å
³ç³»æ¥è¯¢ï¼é£ä¹åºç¨ç¨åºå°±å¯ä»¥ä½¿ç¨æ符åå
¶éæ±çåè½ç»åã
å
³ç³»æ¨¡ååæ档模åçæ··åæ¯æªæ¥æ°æ®åºä¸æ¡å¾å¥½ç路线ã
[^v]: Codd对å
³ç³»æ¨¡åã1ãçåå§æè¿°å®é
ä¸å
许å¨å
³ç³»æ¨¡å¼ä¸ä¸JSONææ¡£é常ç¸ä¼¼ãä»ç§°ä¹ä¸º**éç®ååï¼nonsimple domainsï¼**ãè¿ä¸ªæ³æ³æ¯ï¼ä¸è¡ä¸çå¼ä¸ä¸å®æ¯ä¸ä¸ªåæ°åæå符串ä¸æ ·çåå§æ°æ®ç±»åï¼ä¹å¯ä»¥æ¯ä¸ä¸ªåµå¥çå
³ç³»ï¼è¡¨ï¼ï¼å æ¤å¯ä»¥æä¸ä¸ªä»»æåµå¥çæ ç»æä½ä¸ºä¸ä¸ªå¼ï¼è¿å¾å30å¹´åæ·»å å°SQLä¸çJSONæXMLæ¯æã
## æ°æ®æ¥è¯¢è¯è¨
å½å¼å
¥å
³ç³»æ¨¡åæ¶ï¼å
³ç³»æ¨¡åå
å«äºä¸ç§æ¥è¯¢æ°æ®çæ°æ¹æ³ï¼SQLæ¯ä¸ç§ **声æå¼** æ¥è¯¢è¯è¨ï¼èIMSåCODASYLä½¿ç¨ **å½ä»¤å¼** 代ç æ¥æ¥è¯¢æ°æ®åºãé£æ¯ä»ä¹ææï¼
许å¤å¸¸ç¨çç¼ç¨è¯è¨æ¯å½ä»¤å¼çãä¾å¦ï¼ç»å®ä¸ä¸ªå¨ç©ç©ç§çå表ï¼è¿åå表ä¸ç鲨鱼å¯ä»¥è¿æ ·åï¼
```js
function getSharks() {
var sharks = [];
for (var i = 0; i < animals.length; i++) {
if (animals[i].family === "Sharks") {
sharks.push(animals[i]);
}
}
return sharks;
}
```
å¨å
³ç³»ä»£æ°ä¸ï¼
$$
sharks = Ï_{family = "sharks"}(animals)
$$
Ïï¼å¸è
åæ¯è¥¿æ ¼çï¼æ¯éæ©æä½ç¬¦ï¼åªè¿å符åæ¡ä»¶çå¨ç©ï¼`family="shark"`ã
å®ä¹SQLæ¶ï¼å®ç´§å¯å°éµå¾ªå
³ç³»ä»£æ°çç»æï¼
```sql
SELECT * FROM animals WHERE family ='Sharks';
```
å½ä»¤å¼è¯è¨åè¯è®¡ç®æºä»¥ç¹å®é¡ºåºæ§è¡æäºæä½ãå¯ä»¥æ³è±¡ä¸ä¸ï¼éè¡å°éå代ç ï¼è¯ä¼°æ¡ä»¶ï¼æ´æ°åéï¼å¹¶å³å®æ¯å¦å循ç¯ä¸éã
å¨å£°æå¼æ¥è¯¢è¯è¨ï¼å¦SQLæå
³ç³»ä»£æ°ï¼ä¸ï¼ä½ åªéæå®æéæ°æ®çæ¨¡å¼ - ç»æå¿
须符ååªäºæ¡ä»¶ï¼ä»¥åå¦ä½å°æ°æ®è½¬æ¢ï¼ä¾å¦ï¼æåºï¼åç»åéåï¼ - ä½ä¸æ¯å¦ä½å®ç°è¿ä¸ç®æ ãæ°æ®åºç³»ç»çæ¥è¯¢ä¼åå¨å³å®ä½¿ç¨åªäºç´¢å¼ååªäºè¿æ¥æ¹æ³ï¼ä»¥å以ä½ç§é¡ºåºæ§è¡æ¥è¯¢çå个é¨åã
声æå¼æ¥è¯¢è¯è¨æ¯è¿·äººçï¼å 为å®é常æ¯å½ä»¤å¼APIæ´å ç®æ´å容æãä½æ´éè¦çæ¯ï¼å®è¿éèäºæ°æ®åºå¼æçå®ç°ç»èï¼è¿ä½¿å¾æ°æ®åºç³»ç»å¯ä»¥å¨æ é对æ¥è¯¢åä»»ä½æ´æ¹çæ
åµä¸è¿è¡æ§è½æåã
ä¾å¦ï¼å¨æ¬èå¼å¤´æ示çå½ä»¤ä»£ç ä¸ï¼å¨ç©å表以ç¹å®é¡ºåºåºç°ãå¦ææ°æ®åºæ³è¦å¨åå°åæ¶æªä½¿ç¨çç£ç空é´ï¼åå¯è½éè¦ç§»å¨è®°å½ï¼è¿ä¼æ¹åå¨ç©åºç°ç顺åºãæ°æ®åºè½å¦å®å
¨å°æ§è¡ï¼èä¸ä¼ä¸ææ¥è¯¢ï¼
SQL示ä¾ä¸ç¡®ä¿ä»»ä½ç¹å®ç顺åºï¼å æ¤ä¸å¨æ顺åºæ¯å¦æ¹åãä½æ¯å¦ææ¥è¯¢ç¨å½ä»¤å¼ç代ç æ¥åçè¯ï¼é£ä¹æ°æ®åºå°±æ°¸è¿ä¸å¯è½ç¡®å®ä»£ç æ¯å¦ä¾èµäºæåºãSQLç¸å½æéçåè½æ§ä¸ºæ°æ®åºæä¾äºæ´å¤èªå¨ä¼åç空é´ã
æåï¼å£°æå¼è¯è¨å¾å¾éå并è¡æ§è¡ãç°å¨ï¼CPUçé度éè¿æ ¸å¿(core)çå¢å åå¾æ´å¿«ï¼èä¸æ¯ä»¥æ¯ä»¥åæ´é«çæ¶éé度è¿è¡ã31ããå½ä»¤ä»£ç å¾é¾å¨å¤ä¸ªæ ¸å¿åå¤ä¸ªæºå¨ä¹é´å¹¶è¡åï¼å 为å®æå®äºæ令å¿
须以ç¹å®é¡ºåºæ§è¡ã声æå¼è¯è¨æ´å
·æ并è¡æ§è¡çæ½åï¼å 为å®ä»¬ä»
æå®ç»æç模å¼ï¼èä¸æå®ç¨äºç¡®å®ç»æçç®æ³ãå¨éå½æ
åµä¸ï¼æ°æ®åºå¯ä»¥èªç±ä½¿ç¨æ¥è¯¢è¯è¨ç并è¡å®ç°ã32ãã
### Webä¸ç声æå¼æ¥è¯¢
声æå¼æ¥è¯¢è¯è¨çä¼å¿ä¸ä»
éäºæ°æ®åºã为äºè¯´æè¿ä¸ç¹ï¼è®©æ们å¨ä¸ä¸ªå®å
¨ä¸åçç¯å¢ä¸æ¯è¾å£°æå¼åå½ä»¤å¼æ¹æ³ï¼ä¸ä¸ªWebæµè§å¨ã
åè®¾ä½ æä¸ä¸ªå
³äºæµ·æ´å¨ç©çç½ç«ãç¨æ·å½åæ£å¨æ¥ç鲨鱼页é¢ï¼å æ¤ä½ å°å½åæéç导èªé¡¹ç®â鲨鱼âæ 记为å½åéä¸é¡¹ç®ã
```html
-
Sharks
- Great White Shark
- Tiger Shark
- Hammerhead Shark
-
Whales
- Blue Whale
- Humpback Whale
- Fin Whale
```
ç°å¨æ³è®©å½åæé页é¢çæ é¢å
·æä¸ä¸ªèè²çèæ¯ï¼ä»¥ä¾¿å¨è§è§ä¸çªåºæ¾ç¤ºã使ç¨CSSå®ç°èµ·æ¥é常ç®åï¼
```css
li.selected > p {
background-color: blue;
}
```
è¿éçCSSéæ©å¨`li.selected> p`声æäºæ们æ³è¦åºç¨èè²æ ·å¼çå
ç´ ç模å¼ï¼å³å
¶ç´æ¥ç¶å
ç´ æ¯å
·æ`selected`CSSç±»ç``å
ç´ çææ``å
ç´ ã示ä¾ä¸çå
ç´ `
Sharks
`å¹é
æ¤æ¨¡å¼ï¼ä½` Whales
`ä¸å¹é
ï¼å 为å
¶``ç¶å
ç´ ç¼ºå°`class =âselectedâ`ã
å¦æ使ç¨XSLèä¸æ¯CSSï¼ä½ å¯ä»¥å类似çäºæ
ï¼
```xml
```
è¿éçXPath表达å¼`li[@class='selected']/p`ç¸å½äºä¸ä¾ä¸çCSSéæ©å¨`li.selected> p`ãCSSåXSLçå
±åä¹å¤å¨äºï¼å®ä»¬é½æ¯ç¨äºæå®ææ¡£æ ·å¼ç声æå¼è¯è¨ã
æ³è±¡ä¸ä¸ï¼å¿
须使ç¨å½ä»¤å¼æ¹æ³çæ
åµä¼æ¯å¦ä½ãå¨Javascriptä¸ï¼ä½¿ç¨ **æ档对象模åï¼DOMï¼** APIï¼å
¶ç»æå¯è½å¦ä¸æ示ï¼
```js
var liElements = document.getElementsByTagName("li");
for (var i = 0; i < liElements.length; i++) {
if (liElements[i].className === "selected") {
var children = liElements[i].childNodes;
for (var j = 0; j < children.length; j++) {
var child = children[j];
if (child.nodeType === Node.ELEMENT_NODE && child.tagName === "P") {
child.setAttribute("style", "background-color: blue");
}
}
}
}
```
è¿æ®µJavaScript代ç å½ä»¤å¼å°å°å
ç´ è®¾ç½®ä¸ºèè²èæ¯ï¼ä½æ¯ä»£ç çèµ·æ¥å¾ç³ç³ãä¸ä»
æ¯CSSåXSLçä»·ç©æ´é¿ï¼æ´é¾ç解ï¼èä¸è¿æä¸äºä¸¥éçé®é¢ï¼
* å¦æéå®ç类被移é¤ï¼ä¾å¦ï¼å 为ç¨æ·ç¹å»äºä¸åç页é¢ï¼ï¼å³ä½¿ä»£ç éæ°è¿è¡ï¼èè²èæ¯ä¹ä¸ä¼è¢«ç§»é¤ - å æ¤è¯¥é¡¹ç®å°ä¿æçªåºæ¾ç¤ºï¼ç´å°æ´ä¸ªé¡µé¢è¢«éæ°å è½½ã使ç¨CSSï¼æµè§å¨ä¼èªå¨æ£æµ`li.selected> p`è§åä½æ¶ä¸åéç¨ï¼å¹¶å¨éå®ç类被移é¤åç«å³ç§»é¤èè²èæ¯ã
* å¦æä½ æ³è¦å©ç¨æ°çAPIï¼ä¾å¦`document.getElementsBy ClassNameï¼âselectedâ`ï¼çè³`document.evaluate()`ï¼æ¥æé«æ§è½ï¼åå¿
é¡»éå代ç ãå¦ä¸æ¹é¢ï¼æµè§å¨ä¾åºåå¯ä»¥å¨ä¸ç ´åå
¼å®¹æ§çæ
åµä¸æé«CSSåXPathçæ§è½ã
å¨Webæµè§å¨ä¸ï¼ä½¿ç¨å£°æå¼CSSæ ·å¼æ¯ä½¿ç¨JavaScriptå½ä»¤å¼å°æä½æ ·å¼è¦å¥½å¾å¤ã类似å°ï¼å¨æ°æ®åºä¸ï¼ä½¿ç¨åSQLè¿æ ·ç声æå¼æ¥è¯¢è¯è¨æ¯ä½¿ç¨å½ä»¤å¼æ¥è¯¢APIè¦å¥½å¾å¤[^vi]ã
[^vi]: vi IMSåCODASYLé½ä½¿ç¨å½ä»¤å¼APIãåºç¨ç¨åºé常使ç¨COBOL代ç éåæ°æ®åºä¸çè®°å½ï¼ä¸æ¬¡ä¸æ¡è®°å½ã2,16ãã
### MapReduceæ¥è¯¢
MapReduceæ¯ä¸ä¸ªç±Googleæ¨å¹¿çç¼ç¨æ¨¡åï¼ç¨äºå¨å¤å°æºå¨ä¸æ¹éå¤ç大è§æ¨¡çæ°æ®ã33ããä¸äºNoSQLæ°æ®åå¨ï¼å
æ¬MongoDBåCouchDBï¼æ¯ææéå½¢å¼çMapReduceï¼ä½ä¸ºå¨å¤ä¸ªææ¡£ä¸æ§è¡åªè¯»æ¥è¯¢çæºå¶ã
MapReduceå°[第10ç« ](ch10.md)ä¸ææ´è¯¦ç»çæè¿°ãç°å¨æ们å°ç®è¦è®¨è®ºä¸ä¸MongoDB使ç¨ç模åã
MapReduceæ¢ä¸æ¯ä¸ä¸ªå£°æå¼çæ¥è¯¢è¯è¨ï¼ä¹ä¸æ¯ä¸ä¸ªå®å
¨å½ä»¤å¼çæ¥è¯¢APIï¼èæ¯å¤äºä¸¤è
ä¹é´ï¼æ¥è¯¢çé»è¾ç¨ä»£ç ç段æ¥è¡¨ç¤ºï¼è¿äºä»£ç ç段ä¼è¢«å¤çæ¡æ¶éå¤æ§è°ç¨ãå®åºäº`map`ï¼ä¹ç§°ä¸º`collect`ï¼å`reduce`ï¼ä¹ç§°ä¸º`fold`æ`inject`ï¼å½æ°ï¼ä¸¤ä¸ªå½æ°åå¨äºè®¸å¤å½æ°å¼ç¼ç¨è¯è¨ä¸ã
æ好举ä¾æ¥è§£éMapReduce模åãåè®¾ä½ æ¯ä¸åæµ·æ´çç©å¦å®¶ï¼æ¯å½ä½ çå°æµ·æ´ä¸çå¨ç©æ¶ï¼ä½ é½ä¼å¨æ°æ®åºä¸æ·»å ä¸æ¡è§å¯è®°å½ãç°å¨ä½ æ³çæä¸ä¸ªæ¥åï¼è¯´æä½ æ¯æçå°å¤å°é²¨é±¼ã
å¨PostgreSQLä¸ï¼ä½ å¯ä»¥åè¿æ ·è¡¨è¿°è¿ä¸ªæ¥è¯¢ï¼
```sql
SELECT
date_trunc('month', observation_timestamp) AS observation_month,
sum(num_animals) AS total_animals
FROM observations
WHERE family = 'Sharks'
GROUP BY observation_month;
```
`date_trunc('month'ï¼timestamp)`å½æ°ç¨äºç¡®å®å
å«`timestamp`çæ¥åæ份ï¼å¹¶è¿å代表该æ份å¼å§çå¦ä¸ä¸ªæ¶é´æ³ãæ¢å¥è¯è¯´ï¼å®å°æ¶é´æ³èå
¥ææè¿çæ份ã
è¿ä¸ªæ¥è¯¢é¦å
è¿æ»¤è§å¯è®°å½ï¼ä»¥åªæ¾ç¤ºé²¨é±¼å®¶æçç©ç§ï¼ç¶åæ ¹æ®å®ä»¬åççæ¥åæ份对è§å¯è®°å½æè¿è¡åç»ï¼æåå°å¨è¯¥æçææè§å¯è®°å½ä¸çå°çå¨ç©æ°ç®å èµ·æ¥ã
åæ ·çæ¥è¯¢ç¨MongoDBçMapReduceåè½å¯ä»¥æå¦ä¸æ¥è¡¨è¿°ï¼
```js
db.observations.mapReduce(function map() {
var year = this.observationTimestamp.getFullYear();
var month = this.observationTimestamp.getMonth() + 1;
emit(year + "-" + month, this.numAnimals);
},
function reduce(key, values) {
return Array.sum(values);
},
{
query: {
family: "Sharks"
},
out: "monthlySharkReport"
});
```
* å¯ä»¥å£°æå¼å°æå®ä¸ä¸ªåªèè鲨鱼ç§ç±»çè¿æ»¤å¨ï¼è¿æ¯MongoDBç¹å®çMapReduceæ©å±ï¼ã
* æ¯ä¸ªå¹é
æ¥è¯¢çææ¡£é½ä¼è°ç¨ä¸æ¬¡JavaScriptå½æ°`map`ï¼å°`this`设置为æ档对象ã
* `map`å½æ°ååºä¸ä¸ªé®ï¼å
æ¬å¹´ä»½åæ份çå符串ï¼å¦`"2013-12"`æ`"2014-1"`ï¼åä¸ä¸ªå¼ï¼è¯¥è§å¯è®°å½ä¸çå¨ç©æ°éï¼ã
* `map`ååºçé®å¼å¯¹æé®æ¥åç»ã对äºå
·æç¸åé®ï¼å³ï¼ç¸åçæ份å年份ï¼çææé®å¼å¯¹ï¼è°ç¨ä¸æ¬¡`reduce`å½æ°ã
* `reduce`å½æ°å°ç¹å®æ份å
ææè§æµè®°å½ä¸çå¨ç©æ°éç¸å ã
* å°æç»çè¾åºåå
¥å°`monthlySharkReport`éåä¸ã
ä¾å¦ï¼å设`observations`éåå
å«è¿ä¸¤ä¸ªææ¡£ï¼
```json
{
observationTimestamp: Date.parse( "Mon, 25 Dec 1995 12:34:56 GMT"),
family: "Sharks",
species: "Carcharodon carcharias",
numAnimals: 3
}
{
observationTimestamp: Date.parse("Tue, 12 Dec 1995 16:17:18 GMT"),
family: "Sharks",
species: "Carcharias taurus",
numAnimals: 4
}
```
对æ¯ä¸ªææ¡£é½ä¼è°ç¨ä¸æ¬¡`map`å½æ°ï¼ç»æå°æ¯`emit("1995-12",3)`å`emit("1995-12",4)`ãéåï¼ä»¥`reduce("1995-12",[3,4])`è°ç¨`reduce`å½æ°ï¼å°è¿å`7`ã
mapåreduceå½æ°å¨åè½ä¸ææéå¶ï¼å®ä»¬å¿
é¡»æ¯**纯**å½æ°ï¼è¿æå³çå®ä»¬åªä½¿ç¨ä¼ éç»å®ä»¬çæ°æ®ä½ä¸ºè¾å
¥ï¼å®ä»¬ä¸è½æ§è¡é¢å¤çæ°æ®åºæ¥è¯¢ï¼ä¹ä¸è½æä»»ä½å¯ä½ç¨ãè¿äºéå¶å
许æ°æ®åºä»¥ä»»ä½é¡ºåºè¿è¡ä»»ä½åè½ï¼å¹¶å¨å¤±è´¥æ¶éæ°è¿è¡å®ä»¬ãç¶èï¼mapåreduceå½æ°ä»ç¶æ¯å¼ºå¤§çï¼å®ä»¬å¯ä»¥è§£æå符串ï¼è°ç¨åºå½æ°ï¼æ§è¡è®¡ç®ççã
MapReduceæ¯ä¸ä¸ªç¸å½åºå±çç¼ç¨æ¨¡åï¼ç¨äºè®¡ç®æºé群ä¸çåå¸å¼æ§è¡ãåSQLè¿æ ·çæ´é«çº§çæ¥è¯¢è¯è¨å¯ä»¥ç¨ä¸ç³»åçMapReduceæä½æ¥å®ç°ï¼è§[第10ç« ](ch10.md)ï¼ï¼ä½æ¯ä¹æå¾å¤ä¸ä½¿ç¨MapReduceçåå¸å¼SQLå®ç°ã请注æï¼SQLä¸æ²¡æä»»ä½å
容éå¶å®å¨å个æºå¨ä¸è¿è¡ï¼èMapReduceå¨åå¸å¼æ¥è¯¢æ§è¡ä¸æ²¡æåææã
è½å¤å¨æ¥è¯¢ä¸ä½¿ç¨JavaScript代ç æ¯é«çº§æ¥è¯¢çä¸ä¸ªéè¦ç¹æ§ï¼ä½è¿ä¸éäºMapReduceï¼ä¸äºSQLæ°æ®åºä¹å¯ä»¥ç¨JavaScriptå½æ°è¿è¡æ©å±ã34ãã
MapReduceçä¸ä¸ªå¯ç¨æ§é®é¢æ¯ï¼å¿
é¡»ç¼å两个å¯ååä½çJavaScriptå½æ°ï¼è¿é常æ¯ç¼åå个æ¥è¯¢æ´å°é¾ãæ¤å¤ï¼å£°æå¼æ¥è¯¢è¯è¨ä¸ºæ¥è¯¢ä¼åå¨æä¾äºæ´å¤æºä¼æ¥æé«æ¥è¯¢çæ§è½ãåºäºè¿äºåå ï¼MongoDB 2.2æ·»å äºä¸ç§å«å**èå管é**ç声æå¼æ¥è¯¢è¯è¨çæ¯æã9ããç¨è¿ç§è¯è¨è¡¨è¿°é²¨é±¼è®¡æ°æ¥è¯¢å¦ä¸æ示ï¼
```js
db.observations.aggregate([
{ $match: { family: "Sharks" } },
{ $group: {
_id: {
year: { $year: "$observationTimestamp" },
month: { $month: "$observationTimestamp" }
},
totalAnimals: { $sum: "$numAnimals" } }}
]);
```
èå管éè¯è¨ä¸SQLçåéå
·æ类似表ç°åï¼ä½æ¯å®ä½¿ç¨åºäºJSONçè¯æ³èä¸æ¯SQLçè±è¯å¥åå¼è¯æ³; è¿ç§å·®å¼ä¹è®¸æ¯å£å³é®é¢ãè¿ä¸ªæ
äºçå¯ææ¯NoSQLç³»ç»å¯è½ä¼åç°èªå·±æå¤å°éæ°åæäºSQLï¼å°½ç®¡å¸¦ç伪è£
ã
## å¾æ°æ®æ¨¡å
å¦æ们ä¹åæè§ï¼å¤å¯¹å¤å
³ç³»æ¯ä¸åæ°æ®æ¨¡åä¹é´å
·æåºå«æ§çéè¦ç¹å¾ãå¦æä½ çåºç¨ç¨åºå¤§å¤æ°çå
³ç³»æ¯ä¸å¯¹å¤å
³ç³»ï¼æ ç¶ç»æåæ°æ®ï¼ï¼æè
大å¤æ°è®°å½ä¹é´ä¸åå¨å
³ç³»ï¼é£ä¹ä½¿ç¨æ档模åæ¯åéçã
ä½æ¯ï¼è¦æ¯å¤å¯¹å¤å
³ç³»å¨ä½ çæ°æ®ä¸å¾å¸¸è§å¢ï¼å
³ç³»æ¨¡åå¯ä»¥å¤çå¤å¯¹å¤å
³ç³»çç®åæ
åµï¼ä½æ¯éçæ°æ®ä¹é´çè¿æ¥åå¾æ´å å¤æï¼å°æ°æ®å»ºæ¨¡ä¸ºå¾å½¢æ¾å¾æ´å èªç¶ã
ä¸ä¸ªå¾ç±ä¸¤ç§å¯¹è±¡ç»æï¼**顶ç¹ï¼verticesï¼**ï¼ä¹ç§°ä¸º**èç¹ï¼nodesï¼** æ**å®ä½ï¼entitiesï¼**ï¼ï¼å**è¾¹ï¼edgesï¼**ï¼ ä¹ç§°ä¸º**å
³ç³»ï¼relationshipsï¼**æ**弧 ï¼arcsï¼** ï¼ãå¤ç§æ°æ®å¯ä»¥è¢«å»ºæ¨¡ä¸ºä¸ä¸ªå¾å½¢ãå
¸åçä¾åå
æ¬ï¼
***社交å¾è°±***
顶ç¹æ¯äººï¼è¾¹æ示åªäºäººå½¼æ¤è®¤è¯ã
***ç½ç»å¾è°±***
顶ç¹æ¯ç½é¡µï¼è¾¹ç¼è¡¨ç¤ºæåå
¶ä»é¡µé¢çHTMLé¾æ¥ã
***å
¬è·¯æéè·¯ç½ç»***
顶ç¹æ¯äº¤åè·¯å£ï¼è¾¹çº¿ä»£è¡¨å®ä»¬ä¹é´çéè·¯æé路线ã
å¯ä»¥å°é£äºä¼æå¨ç¥çç®æ³è¿ç¨å°è¿äºå¾ä¸ï¼ä¾å¦ï¼æ±½è½¦å¯¼èªç³»ç»æç´¢éè·¯ç½ç»ä¸ä¸¤ç¹ä¹é´çæçè·¯å¾ï¼PageRankå¯ä»¥ç¨å¨ç½ç»å¾ä¸æ¥ç¡®å®ç½é¡µçæµè¡ç¨åº¦ï¼ä»èç¡®å®è¯¥ç½é¡µå¨æç´¢ç»æä¸çæåã
å¨ååç»åºçä¾åä¸ï¼å¾ä¸çææ顶ç¹ä»£è¡¨äºç¸åç±»åçäºç©ï¼äººï¼ç½é¡µæ交åè·¯å£ï¼ãä¸è¿ï¼å¾å¹¶ä¸å±éäºè¿æ ·çåç±»æ°æ®ï¼åæ ·å¼ºå¤§å°æ¯ï¼å¾æä¾äºä¸ç§ä¸è´çæ¹å¼ï¼ç¨æ¥å¨å个æ°æ®åå¨ä¸åå¨å®å
¨ä¸åç±»åç对象ãä¾å¦ï¼Facebookç»´æ¤ä¸ä¸ªå
å«è®¸å¤ä¸åç±»åç顶ç¹åè¾¹çå个å¾ï¼é¡¶ç¹è¡¨ç¤ºäººï¼å°ç¹ï¼äºä»¶ï¼ç¾å°åç¨æ·çè¯è®ºï¼è¾¹ç¼è¡¨ç¤ºåªäºäººæ¯å½¼æ¤çæåï¼åªä¸ªç¾å°åçå¨ä½å¤ï¼è°è¯è®ºäºåªæ¡æ¶æ¯ï¼è°åä¸äºåªä¸ªäºä»¶ï¼ççã35ãã
å¨æ¬èä¸ï¼æ们å°ä½¿ç¨[å¾2-5](img/fig2-5.png)æ示ç示ä¾ãå®å¯ä»¥ä»ç¤¾äº¤ç½ç»æ系谱æ°æ®åºä¸è·å¾ï¼å®æ¾ç¤ºäºä¸¤ä¸ªäººï¼æ¥èªç±è¾¾è·å·çLucyåæ¥èªæ³å½BeauneçAlainãä»ä»¬å·²å©ï¼ä½å¨ä¼¦æ¦ã
![](img/fig2-5.png)
**å¾2-5 å¾æ°æ®ç»æ示ä¾ï¼æ¡ä»£è¡¨é¡¶ç¹ï¼ç®å¤´ä»£è¡¨è¾¹ï¼**
æå ç§ä¸åä½ç¸å
³çæ¹æ³ç¨æ¥æ建åæ¥è¯¢å¾è¡¨ä¸çæ°æ®ãå¨æ¬èä¸ï¼æ们å°è®¨è®ºå±æ§å¾æ¨¡åï¼ç±Neo4jï¼TitanåInfiniteGraphå®ç°ï¼åä¸å
ç»åå¨ï¼triple-storeï¼æ¨¡åï¼ç±Datomicï¼AllegroGraphçå®ç°ï¼ãæ们å°æ¥çå¾çä¸ç§å£°æå¼æ¥è¯¢è¯è¨ï¼Cypherï¼SPARQLåDatalogãé¤æ¤ä¹å¤ï¼è¿æåGremlin ã36ãè¿æ ·çå¾å½¢æ¥è¯¢è¯è¨ååPregelè¿æ ·çå¾å½¢å¤çæ¡æ¶ï¼è§[第10ç« ](ch10.md)ï¼ã
### å±æ§å¾
å¨å±æ§å¾æ¨¡åä¸ï¼æ¯ä¸ª**顶ç¹ï¼vertexï¼** å
æ¬ï¼
* å¯ä¸çæ è¯ç¬¦
* ä¸ç» **åºè¾¹ï¼outgoing edgesï¼**
* ä¸ç» **å
¥è¾¹ï¼ingoing edgesï¼**
* ä¸ç»å±æ§ï¼é®å¼å¯¹ï¼
æ¯æ¡ **è¾¹ï¼edgeï¼** å
æ¬ï¼
* å¯ä¸æ è¯ç¬¦
* **è¾¹çèµ·ç¹/å°¾é¨é¡¶ç¹ï¼tail vertexï¼**
* **è¾¹çç»ç¹/头é¨é¡¶ç¹ï¼head vertexï¼**
* æ述两个顶ç¹ä¹é´å
³ç³»ç±»åçæ ç¾
* ä¸ç»å±æ§ï¼é®å¼å¯¹ï¼
å¯ä»¥å°å¾åå¨çä½ç±ä¸¤ä¸ªå
³ç³»è¡¨ç»æï¼ä¸ä¸ªåå¨é¡¶ç¹ï¼å¦ä¸ä¸ªåå¨è¾¹ï¼å¦[ä¾2-2]()æ示ï¼è¯¥æ¨¡å¼ä½¿ç¨PostgreSQL JSONæ°æ®ç±»åæ¥åå¨æ¯ä¸ªé¡¶ç¹ææ¯æ¡è¾¹çå±æ§ï¼ã头é¨åå°¾é¨é¡¶ç¹ç¨æ¥åå¨æ¯æ¡è¾¹ï¼å¦æä½ æ³è¦ä¸ç»é¡¶ç¹çè¾å
¥æè¾åºè¾¹ï¼ä½ å¯ä»¥åå«éè¿`head_vertex`æ`tail_vertex`æ¥æ¥è¯¢`edges`表ã
**ä¾2-2 使ç¨å
³ç³»æ¨¡å¼æ¥è¡¨ç¤ºå±æ§å¾**
```sql
CREATE TABLE vertices (
vertex_id INTEGER PRIMARY KEY,
properties JSON
);
CREATE TABLE edges (
edge_id INTEGER PRIMARY KEY,
tail_vertex INTEGER REFERENCES vertices (vertex_id),
head_vertex INTEGER REFERENCES vertices (vertex_id),
label TEXT,
properties JSON
);
CREATE INDEX edges_tails ON edges (tail_vertex);
CREATE INDEX edges_heads ON edges (head_vertex);
```
å
³äºè¿ä¸ªæ¨¡åçä¸äºéè¦æ¹é¢æ¯ï¼
1. ä»»ä½é¡¶ç¹é½å¯ä»¥æä¸æ¡è¾¹è¿æ¥å°ä»»ä½å
¶ä»é¡¶ç¹ã没æ模å¼éå¶åªç§äºç©å¯ä¸å¯ä»¥å
³èã
2. ç»å®ä»»ä½é¡¶ç¹ï¼å¯ä»¥é«æå°æ¾å°å®çå
¥è¾¹ååºè¾¹ï¼ä»èéåå¾ï¼å³æ²¿çä¸ç³»å顶ç¹çè·¯å¾åå移å¨ãï¼è¿å°±æ¯ä¸ºä»ä¹[ä¾2-2]()å¨`tail_vertex`å`head_vertex`åä¸é½æç´¢å¼çåå ãï¼
3. éè¿å¯¹ä¸åç±»åçå
³ç³»ä½¿ç¨ä¸åçæ ç¾ï¼å¯ä»¥å¨ä¸ä¸ªå¾ä¸åå¨å ç§ä¸åçä¿¡æ¯ï¼åæ¶ä»ç¶ä¿æä¸ä¸ªæ¸
æ°çæ°æ®æ¨¡åã
è¿äºç¹æ§ä¸ºæ°æ®å»ºæ¨¡æä¾äºå¾å¤§ççµæ´»æ§ï¼å¦[å¾2-5](img/fig2-5.png)æ示ãå¾ä¸æ¾ç¤ºäºä¸äºä¼ ç»å
³ç³»æ¨¡å¼é¾ä»¥è¡¨è¾¾çäºæ
ï¼ä¾å¦ä¸åå½å®¶çä¸åå°åºç»æï¼æ³å½æçåå·ï¼ç¾å½æä¸åçå·åå·ï¼ï¼å½ä¸å½çæªäºï¼å
忽ç¥ä¸»æå½å®¶åå½å®¶é综å¤æççæåï¼ï¼ä¸åçæ°æ®ç²åº¦ï¼Lucyç°å¨çä½æ被æå®ä¸ºä¸ä¸ªåå¸ï¼è她çåºçå°ç¹åªæ¯å¨ä¸ä¸ªå·ç级å«ï¼ã
ä½ å¯ä»¥æ³è±¡å»¶ä¼¸å¾è¿è½å
æ¬è®¸å¤å
³äºLucyåAlainï¼æå
¶ä»äººçå
¶ä»æ´å¤çäºå®ãä¾å¦ï¼ä½ å¯ä»¥ç¨å®æ¥è¡¨ç¤ºé£ç©è¿æï¼ä¸ºæ¯ä¸ªè¿ææºå¢å ä¸ä¸ªé¡¶ç¹ï¼å¹¶å¢å 人ä¸è¿ææºä¹é´çä¸æ¡è¾¹æ¥æ示ä¸ç§è¿ææ
åµï¼ï¼å¹¶é¾æ¥å°è¿ææºï¼æ¯ä¸ªè¿ææºå
·æä¸ç»é¡¶ç¹ç¨æ¥æ¾ç¤ºåªäºé£ç©å«æåªäºç©è´¨ãç¶åï¼ä½ å¯ä»¥åä¸ä¸ªæ¥è¯¢ï¼æ¾åºæ¯ä¸ªäººåä»ä¹æ¯å®å
¨çãå¾è¡¨å¨å¯æ¼åæ§æ¯å¯æä¼å¿çï¼å½ååºç¨ç¨åºæ·»å åè½æ¶ï¼å¯ä»¥è½»æ¾æ©å±å¾ä»¥éåºåºç¨ç¨åºæ°æ®ç»æçååã
### Cypheræ¥è¯¢è¯è¨
Cypheræ¯å±æ§å¾ç声æå¼æ¥è¯¢è¯è¨ï¼ä¸ºNeo4jå¾å½¢æ°æ®åºèåæã37ããï¼å®æ¯ä»¥çµå½±âé»å®¢å¸å½âä¸çä¸ä¸ªè§è²æ¥å½åçï¼èä¸å¯ç æ¯ä¸çå¯ç æ å
³ã38ããï¼
[ä¾2-3]()æ¾ç¤ºäºå°[å¾2-5](img/fig2-5.png)ç左边é¨åæå
¥å¾å½¢æ°æ®åºçCypheræ¥è¯¢ãå¯ä»¥ç±»ä¼¼å°æ·»å å¾çå
¶ä½é¨åï¼ä¸ºäºä¾¿äºé
读èçç¥ãæ¯ä¸ªé¡¶ç¹é½æä¸ä¸ªå`USA`æ`Idaho`è¿æ ·ç符å·å称ï¼æ¥è¯¢çå
¶ä»é¨åå¯ä»¥ä½¿ç¨è¿äºå称å¨é¡¶ç¹ä¹é´å建边ï¼ä½¿ç¨ç®å¤´ç¬¦å·ï¼`ï¼Idahoï¼ - [ï¼WITHIN] ->ï¼USAï¼`å建ä¸æ¡æ 记为`WITHIN`çè¾¹ï¼`Idaho`为尾èç¹ï¼`USA`为头èç¹ã
**ä¾2-3 å°å¾2-5ä¸çæ°æ®åé表示为Cypheræ¥è¯¢**
```cypher
CREATE
(NAmerica:Location {name:'North America', type:'continent'}),
(USA:Location {name:'United States', type:'country' }),
(Idaho:Location {name:'Idaho', type:'state' }),
(Lucy:Person {name:'Lucy' }),
(Idaho) -[:WITHIN]-> (USA) -[:WITHIN]-> (NAmerica),
(Lucy) -[:BORN_IN]-> (Idaho)
```
å½[å¾2-5](img/fig2-5.png)çææ顶ç¹å边被添å å°æ°æ®åºåï¼è®©æ们æäºæ趣çé®é¢ï¼ä¾å¦ï¼æ¾å°ææä»ç¾å½ç§»æ°å°æ¬§æ´²ç人çååãæ´ç¡®åå°è¯´ï¼è¿éæ们æ³è¦æ¾å°ç¬¦åä¸é¢æ¡ä»¶çææ顶ç¹ï¼å¹¶ä¸è¿åè¿äºé¡¶ç¹ç`name`å±æ§ï¼è¯¥é¡¶ç¹æ¥æä¸æ¡è¿å°ç¾å½ä»»ä¸ä½ç½®ç`BORN_IN`è¾¹ï¼åä¸æ¡è¿å°æ¬§æ´²çä»»ä¸ä½ç½®ç`LIVING_IN`è¾¹ã
[ä¾2-4]()å±ç¤ºäºå¦ä½å¨Cypherä¸è¡¨è¾¾è¿ä¸ªæ¥è¯¢ãå¨MATCHåå¥ä¸ä½¿ç¨ç¸åçç®å¤´ç¬¦å·æ¥æ¥æ¾å¾ä¸ç模å¼ï¼`(person) -[:BORN_IN]-> ()` å¯ä»¥å¹é
`BORN_IN`è¾¹çä»»æ两个顶ç¹ã该边çå°¾èç¹è¢«ç»å®äºåé`person`ï¼å¤´èç¹åæªè¢«ç»å®ã
**ä¾2-4 æ¥æ¾ææä»ç¾å½ç§»æ°å°æ¬§æ´²ç人çCypheræ¥è¯¢ï¼**
```cypher
MATCH
(person) -[:BORN_IN]-> () -[:WITHIN*0..]-> (us:Location {name:'United States'}),
(person) -[:LIVES_IN]-> () -[:WITHIN*0..]-> (eu:Location {name:'Europe'})
RETURN person.name
```
æ¥è¯¢æå¦ä¸æ¥è§£è¯»ï¼
> æ¾å°æ»¡è¶³ä»¥ä¸ä¸¤ä¸ªæ¡ä»¶çææ顶ç¹ï¼ç§°ä¹ä¸ºperson顶ç¹ï¼ï¼
> 1. `person`顶ç¹æ¥æä¸æ¡å°æ个顶ç¹ç`BORN_IN`åºè¾¹ãä»é£ä¸ªé¡¶ç¹å¼å§ï¼æ²¿çä¸ç³»å`WITHIN`åºè¾¹æç»å°è¾¾ä¸ä¸ªç±»å为`Location`ï¼`name`å±æ§ä¸º`United States`ç顶ç¹ã
>
> 2. `person`顶ç¹è¿æ¥æä¸æ¡`LIVES_IN`åºè¾¹ã沿çè¿æ¡è¾¹ï¼å¯ä»¥éè¿ä¸ç³»å`WITHIN`åºè¾¹æç»å°è¾¾ä¸ä¸ªç±»å为`Location`ï¼`name`å±æ§ä¸º`Europe`ç顶ç¹ã
>
> 对äºè¿æ ·ç`Person`顶ç¹ï¼è¿åå
¶`name`å±æ§ã
æ§è¡è¿æ¡æ¥è¯¢å¯è½ä¼æå ç§å¯è¡çæ¥è¯¢è·¯å¾ãè¿éç»åºçæ述建议é¦å
æ«ææ°æ®åºä¸çææ人ï¼æ£æ¥æ¯ä¸ªäººçåºçå°åå±
ä½å°ï¼ç¶ååªè¿å符åæ¡ä»¶çé£äºäººã
çä»·å°ï¼ä¹å¯ä»¥ä»ä¸¤ä¸ª`Location`顶ç¹å¼å§ååå°æ¥æ¾ãåå¦`name`å±æ§ä¸æç´¢å¼ï¼åå¯ä»¥é«æå°æ¾å°ä»£è¡¨ç¾å½å欧洲ç两个顶ç¹ãç¶åï¼æ²¿çææ`WITHIN`å
¥è¾¹ï¼å¯ä»¥ç»§ç»æ¥æ¾åºææå¨ç¾å½å欧洲çä½ç½®ï¼å·ï¼å°åºï¼åå¸çï¼ãæåï¼æ¥æ¾åºé£äºå¯ä»¥ç±`BORN_IN`æ`LIVES_IN`å
¥è¾¹å°é£äºä½ç½®é¡¶ç¹ç人ã
é常对äºå£°æå¼æ¥è¯¢è¯è¨æ¥è¯´ï¼å¨ç¼åæ¥è¯¢è¯å¥æ¶ï¼ä¸éè¦æå®æ§è¡ç»èï¼æ¥è¯¢ä¼åç¨åºä¼èªå¨éæ©é¢æµæçæé«ççç¥ï¼å æ¤ä½ å¯ä»¥ç»§ç»ç¼ååºç¨ç¨åºçå
¶ä»é¨åã
### SQLä¸çå¾æ¥è¯¢
[ä¾2-2]()建议å¨å
³ç³»æ°æ®åºä¸è¡¨ç¤ºå¾æ°æ®ãä½æ¯ï¼å¦ææå¾æ°æ®æ¾å
¥å
³ç³»ç»æä¸ï¼æ们æ¯å¦ä¹å¯ä»¥ä½¿ç¨SQLæ¥è¯¢å®ï¼
çæ¡æ¯è¯å®çï¼ä½æäºå°é¾ãå¨å
³ç³»æ°æ®åºä¸ï¼ä½ é常ä¼äºå
ç¥éå¨æ¥è¯¢ä¸éè¦åªäºè¿æ¥ãå¨å¾æ¥è¯¢ä¸ï¼ä½ å¯è½éè¦å¨æ¾å°å¾
æ¥æ¾ç顶ç¹ä¹åï¼éåå¯åæ°éçè¾¹ãä¹å°±æ¯è¯´ï¼è¿æ¥çæ°éäºå
并ä¸ç¡®å®ã
å¨æ们çä¾åä¸ï¼è¿åçå¨Cypheræ¥è¯¢ä¸ç`() -[:WITHIN*0..]-> ()`è§åä¸ãä¸ä¸ªäººç`LIVES_IN`è¾¹å¯ä»¥æåä»»ä½ç±»åçä½ç½®ï¼è¡éï¼åå¸ï¼å°åºï¼å°åºï¼å½å®¶çãåå¸å¯ä»¥å¨ä¸ä¸ªå°åºï¼å¨ä¸ä¸ªå·å
çä¸ä¸ªå°åºï¼å¨ä¸ä¸ªå½å®¶å
çä¸ä¸ªå·ççã`LIVES_IN`è¾¹å¯ä»¥ç´æ¥æåæ£å¨æ¥æ¾çä½ç½®ï¼æè
ä¸ä¸ªå¨ä½ç½®å±æ¬¡ç»æä¸éäºæ°å±çä½ç½®ã
å¨Cypherä¸ï¼ç¨`WITHIN * 0`é常ç®æ´å°è¡¨è¿°äºä¸è¿°äºå®ï¼â沿ç`WITHIN`è¾¹ï¼é¶æ¬¡æå¤æ¬¡âãå®å¾åæ£å表达å¼ä¸ç`*`è¿ç®ç¬¦ã
èªSQL:1999ï¼æ¥è¯¢å¯åé¿åº¦éåè·¯å¾çææ³å¯ä»¥ä½¿ç¨ç§°ä¸º**éå½å
¬ç¨è¡¨è¡¨è¾¾å¼**ï¼`WITH RECURSIVE`è¯æ³ï¼çä¸è¥¿æ¥è¡¨ç¤ºã[ä¾2-5]()æ¾ç¤ºäºåæ ·çæ¥è¯¢ - æ¥æ¾ä»ç¾å½ç§»æ°å°æ¬§æ´²ç人çå§å - å¨SQL使ç¨è¿ç§ææ¯ï¼PostgreSQLï¼IBM DB2ï¼OracleåSQL Serveråæ¯æï¼æ¥è¡¨è¿°ãä½æ¯ï¼ä¸Cypherç¸æ¯ï¼å
¶è¯æ³é常笨æã
**ä¾2-5 ä¸ç¤ºä¾2-4åæ ·çæ¥è¯¢ï¼å¨SQLä¸ä½¿ç¨éå½å
¬ç¨è¡¨è¡¨è¾¾å¼è¡¨ç¤º**
```sql
WITH RECURSIVE
-- in_usa å
å«ææçç¾å½å¢å
çä½ç½®ID
in_usa(vertex_id) AS (
SELECT vertex_id FROM vertices WHERE properties ->> 'name' = 'United States'
UNION
SELECT edges.tail_vertex FROM edges
JOIN in_usa ON edges.head_vertex = in_usa.vertex_id
WHERE edges.label = 'within'
),
-- in_europe å
å«ææç欧洲å¢å
çä½ç½®ID
in_europe(vertex_id) AS (
SELECT vertex_id FROM vertices WHERE properties ->> 'name' = 'Europe'
UNION
SELECT edges.tail_vertex FROM edges
JOIN in_europe ON edges.head_vertex = in_europe.vertex_id
WHERE edges.label = 'within' ),
-- born_in_usa å
å«äºææç±»å为Personï¼ä¸åºçå¨ç¾å½ç顶ç¹
born_in_usa(vertex_id) AS (
SELECT edges.tail_vertex FROM edges
JOIN in_usa ON edges.head_vertex = in_usa.vertex_id
WHERE edges.label = 'born_in' ),
-- lives_in_europe å
å«äºææç±»å为Personï¼ä¸å±
ä½å¨æ¬§æ´²ç顶ç¹ã
lives_in_europe(vertex_id) AS (
SELECT edges.tail_vertex FROM edges
JOIN in_europe ON edges.head_vertex = in_europe.vertex_id
WHERE edges.label = 'lives_in')
SELECT vertices.properties ->> 'name'
FROM vertices
JOIN born_in_usa ON vertices.vertex_id = born_in_usa.vertex_id
JOIN lives_in_europe ON vertices.vertex_id = lives_in_europe.vertex_id;
```
* é¦å
ï¼æ¥æ¾`name`å±æ§ä¸º`United States`ç顶ç¹ï¼å°å
¶ä½ä¸º`in_usa`顶ç¹çéåç第ä¸ä¸ªå
ç´ ã
* ä»`in_usa`éåç顶ç¹åºåï¼æ²¿çææç`with_in`å
¥è¾¹ï¼å°å
¶å°¾é¡¶ç¹å å
¥åä¸éåï¼ä¸æéå½ç´å°ææ`with_in`å
¥è¾¹é½è¢«è®¿é®å®æ¯ã
* åçï¼ä»`name`å±æ§ä¸º`Europe`ç顶ç¹åºåï¼å»ºç«`in_europe`顶ç¹çéåã
* 对äº`in_usa`éåä¸çæ¯ä¸ªé¡¶ç¹ï¼æ ¹æ®`born_in`å
¥è¾¹æ¥æ¥æ¾åºçå¨ç¾å½æ个å°æ¹ç人ã
* åæ ·ï¼å¯¹äº`in_europe`éåä¸çæ¯ä¸ªé¡¶ç¹ï¼æ ¹æ®`lives_in`å
¥è¾¹æ¥æ¥æ¾å±
ä½å¨æ¬§æ´²ç人ã
* æåï¼æå¨ç¾å½åºçç人çéåä¸å¨æ¬§æ´²å±
ä½ç人çéåç¸äº¤ã
åä¸ä¸ªæ¥è¯¢ï¼ç¨æä¸ä¸ªæ¥è¯¢è¯è¨å¯ä»¥åæ4è¡ï¼èç¨å¦ä¸ä¸ªæ¥è¯¢è¯è¨éè¦29è¡ï¼è¿æ°æ°è¯´æäºä¸åçæ°æ®æ¨¡åæ¯ä¸ºä¸åçåºç¨åºæ¯è设计çãéæ©éååºç¨ç¨åºçæ°æ®æ¨¡åé常éè¦ã
### ä¸å
ç»åå¨åSPARQL
ä¸å
ç»åå¨æ¨¡å¼å¤§ä½ä¸ä¸å±æ§å¾æ¨¡åç¸åï¼ç¨ä¸åçè¯æ¥æè¿°ç¸åçæ³æ³ãä¸è¿ä»ç¶å¼å¾è®¨è®ºï¼å 为ä¸å
ç»åå¨æå¾å¤ç°æçå·¥å
·åè¯è¨ï¼è¿äºå·¥å
·åè¯è¨å¯¹äºæ建åºç¨ç¨åºçå·¥å
·ç®±å¯è½æ¯å®è´µçè¡¥å
ã
å¨ä¸å
ç»åå¨ä¸ï¼ææä¿¡æ¯é½ä»¥é常ç®åçä¸é¨å表示形å¼åå¨ï¼**主è¯**ï¼**è°è¯**ï¼**宾è¯**ï¼ãä¾å¦ï¼ä¸å
ç» **(åå§, å欢 ,é¦è)** ä¸ï¼**åå§** æ¯ä¸»è¯ï¼**å欢** æ¯è°è¯ï¼å¨è¯ï¼ï¼**é¦è** æ¯å¯¹è±¡ã
ä¸å
ç»ç主è¯ç¸å½äºå¾ä¸çä¸ä¸ªé¡¶ç¹ãè宾è¯æ¯ä¸é¢ä¸¤è
ä¹ä¸ï¼
1. åå§æ°æ®ç±»åä¸çå¼ï¼ä¾å¦å符串ææ°åãå¨è¿ç§æ
åµä¸ï¼ä¸å
ç»çè°è¯å宾è¯ç¸å½äºä¸»è¯é¡¶ç¹ä¸çå±æ§çé®åå¼ãä¾å¦ï¼`(lucy, age, 33)`å°±åå±æ§`{âageâï¼33}`ç顶ç¹lucyã
2. å¾ä¸çå¦ä¸ä¸ªé¡¶ç¹ãå¨è¿ç§æ
åµä¸ï¼è°è¯æ¯å¾ä¸çä¸æ¡è¾¹ï¼ä¸»è¯æ¯å
¶å°¾é¨é¡¶ç¹ï¼è宾è¯æ¯å
¶å¤´é¨é¡¶ç¹ãä¾å¦ï¼å¨`(lucy, marriedTo, alain)`ä¸ä¸»è¯å宾è¯`lucy`å`alain`é½æ¯é¡¶ç¹ï¼å¹¶ä¸è°è¯`marriedTo`æ¯è¿æ¥ä»ä»¬çè¾¹çæ ç¾ã
[ä¾2-6]()æ¾ç¤ºäºä¸[ä¾2-3]()ç¸åçæ°æ®ï¼ä»¥ç§°ä¸ºTurtleçæ ¼å¼ï¼Notation3ï¼N3ï¼ã39ãï¼çä¸ä¸ªåéå½¢å¼åæä¸å
ç»ã
**ä¾2-6 å¾2-5ä¸çæ°æ®åéï¼è¡¨ç¤ºä¸ºTurtleä¸å
ç»**
```reStructuredText
@prefix : .
_:lucy a :Person.
_:lucy :name "Lucy".
_:lucy :bornIn _:idaho.
_:idaho a :Location.
_:idaho :name "Idaho".
_:idaho :type "state".
_:idaho :within _:usa.
_:usa a :Location
_:usa :name "United States"
_:usa :type "country".
_:usa :within _:namerica.
_:namerica a :Location
_:namerica :name "North America"
_:namerica :type :"continent"
```
å¨è¿ä¸ªä¾åä¸ï¼å¾ç顶ç¹è¢«å为ï¼`_ï¼someName`ãè¿ä¸ªåå并ä¸æå³çè¿ä¸ªæ件以å¤çä»»ä½ä¸è¥¿ãå®çåå¨åªæ¯å¸®å©æ们æç¡®åªäºä¸å
ç»å¼ç¨äºåä¸é¡¶ç¹ãå½è°è¯è¡¨ç¤ºè¾¹æ¶ï¼è¯¥å®¾è¯æ¯ä¸ä¸ªé¡¶ç¹ï¼å¦`_:idaho :within _:usa.`ãå½è°è¯æ¯ä¸ä¸ªå±æ§æ¶ï¼è¯¥å®¾è¯æ¯ä¸ä¸ªå符串ï¼å¦`_:usa :name "United States"`
ä¸éåä¸éå°éå¤ç¸åç主è¯çèµ·æ¥ç¸å½éå¤ï¼ä½å¹¸è¿çæ¯ï¼å¯ä»¥ä½¿ç¨åå·æ¥è¯´æå
³äºåä¸ä¸»è¯çå¤ä¸ªäºæ
ãè¿ä½¿å¾Turtleæ ¼å¼ç¸å½ä¸éï¼å¯è¯»æ§å¼ºï¼åè§[ä¾2-7]()ã
**ä¾2-7 ä¸ç§ç¸å¯¹ä¾2-6åå
¥æ°æ®çæ´ä¸ºç®æ´çæ¹æ³ã**
```
@prefix : .
_:lucy a :Person; :name "Lucy"; :bornIn _:idaho.
_:idaho a :Location; :name "Idaho"; :type "state"; :within _:usa
_:usa a :Loaction; :name "United States"; :type "country"; :within _:namerica.
_:namerica a :Location; :name "North America"; :type "continent".
```
#### è¯ä¹ç½ç»
å¦æä½ é
读æ´å¤å
³äºä¸å
ç»åå¨çä¿¡æ¯ï¼ä½ å¯è½ä¼è¢«å·å
¥å
³äºè¯ä¹ç½ç»çæç« æ¼©æ¶¡ä¸ãä¸å
ç»åå¨æ°æ®æ¨¡åå®å
¨ç¬ç«äºè¯ä¹ç½ç»ï¼ä¾å¦ï¼Datomicã40ãæ¯ä¸å
ç»åå¨[^vii]ï¼å¹¶æ²¡æ声称ä¸å®æä»»ä½å
³ç³»ãä½æ¯ï¼ç±äºå¨å¾å¤äººç¼ä¸è¿ä¸¤è
ç´§å¯ç¸è¿ï¼æ们åºè¯¥ç®è¦å°è®¨è®ºä¸ä¸ã
[^vii]: ä»ææ¯ä¸è®²ï¼Datomic使ç¨çæ¯äºå
ç»èä¸æ¯ä¸å
ç»ï¼ä¸¤ä¸ªé¢å¤çå段æ¯ç¨äºçæ¬æ§å¶çå
æ°æ®
ä»æ¬è´¨ä¸è®²è¯ä¹ç½æ¯ä¸ä¸ªç®åä¸åççæ³æ³ï¼ç½ç«å·²ç»å°ä¿¡æ¯åå¸ä¸ºæååå¾çä¾äººç±»é
读ï¼ä¸ºä»ä¹ä¸å°ä¿¡æ¯ä½ä¸ºæºå¨å¯è¯»çæ°æ®ä¹åå¸ç»è®¡ç®æºå¢ï¼**èµæºæè¿°æ¡æ¶**ï¼RDFï¼ã41ãçç®çæ¯ä½ä¸ºä¸åç½ç«ä»¥ä¸è´çæ ¼å¼åå¸æ°æ®çä¸ç§æºå¶ï¼å
许æ¥èªä¸åç½ç«çæ°æ®èªå¨å并æ**ä¸ä¸ªæ°æ®ç½ç»** - ä¸ç§äºèç½èå´å
çâå
³äºä¸åçæ°æ®åºâã
ä¸å¹¸çæ¯ï¼è¿ä¸ªè¯ä¹ç½å¨äºåä¸ä¸çºªå被è¿åº¦ä½¿ç¨ï¼ä½å°ç®å为æ¢æ²¡æä»»ä½è¿¹è±¡è¡¨æå·²å¨å®è·µä¸å®ç°ï¼è¿ä½¿å¾è®¸å¤äººå²ä¹ä»¥é¼»ãå®è¿éåäºè¿å¤ç令人ç¼è±ç¼ä¹±ç缩ç¥è¯ï¼è¿äºå¤æçæ åæè®®åçå¦èªå¤§çè¦æã
ç¶èï¼å¦æä»ç»è§å¯è¿äºå¤±è´¥ï¼è¯ä¹Web项ç®è¿æ¯æ¥æå¾å¤ä¼ç§çå·¥ä½ææãå³ä½¿ä½ 没æå
´è¶£å¨è¯ä¹ç½ä¸åå¸RDFæ°æ®ï¼ä¸å
ç»ä¹å¯ä»¥æ为åºç¨ç¨åºçè¯å¥½å
é¨æ°æ®æ¨¡åã
#### RDFæ°æ®æ¨¡å
[ä¾2-7]()ä¸ä½¿ç¨çTurtleè¯è¨æ¯ä¸ç§ç¨äºRDFæ°æ®ç人å¯è¯»æ ¼å¼ãææ¶åï¼RDFä¹å¯ä»¥ä»¥XMLæ ¼å¼ç¼åï¼ä¸è¿å®æåæ ·çäºæ
ä¼ç¸å¯¹å°å¦ï¼åè§[ä¾2-8]()ãTurtle/N3æ¯æ´å¯åçï¼å 为å®æ´å®¹æé
读ï¼åApache Jena ã42ãè¿æ ·çå·¥å
·å¯ä»¥æ ¹æ®éè¦å¨ä¸åçRDFæ ¼å¼ä¹é´è¿è¡èªå¨è½¬æ¢ã
**ä¾2-8 ç¨RDF/XMLè¯æ³è¡¨ç¤ºä¾2-7çæ°æ®**
```xml
Idaho
state
United States
country
North America
continent
Lucy
```
RDFæä¸äºå¥æªä¹å¤ï¼å 为å®æ¯ä¸ºäºå¨äºèç½ä¸äº¤æ¢æ°æ®è设计çãä¸å
ç»ç主è¯ï¼è°è¯å宾è¯é常æ¯URIãä¾å¦ï¼è°è¯å¯è½æ¯ä¸ä¸ªURIï¼å¦ ``æ``ï¼èä¸ä»
ä»
æ¯`WITHIN`æ`LIVES_IN`ãè¿ä¸ªè®¾è®¡èåçåå 为äºè®©ä½ è½å¤æä½ çæ°æ®åå
¶ä»äººçæ°æ®ç»åèµ·æ¥ï¼å¦æä»ä»¬èµäºåè¯`within`æè
`lives_in`ä¸åçå«ä¹ï¼ä¸¤è
ä¹ä¸ä¼å²çªï¼å 为å®ä»¬çè°è¯å®é
ä¸æ¯``å``ã
ä»RDFçè§åº¦æ¥çï¼URL `` ä¸ä¸å®éè¦è½è§£ææä»ä¹ä¸è¥¿ï¼å®åªæ¯ä¸ä¸ªå½å空é´ã为é¿å
ä¸`http://URL`æ··æ·ï¼æ¬èä¸ç示ä¾ä½¿ç¨ä¸å¯è§£æçURIï¼å¦`urnï¼exampleï¼within`ã幸è¿çæ¯ï¼ä½ åªéå¨æ件顶é¨æå®ä¸ä¸ªåç¼ï¼ç¶åå°±ä¸ç¨å管äºã
### SPARQLæ¥è¯¢è¯è¨
**SPARQL**æ¯ä¸ç§ç¨äºä¸å
ç»åå¨çé¢åRDFæ°æ®æ¨¡åçæ¥è¯¢è¯è¨ï¼ã43ããï¼å®æ¯SPARQLåè®®åRDFæ¥è¯¢è¯è¨ç缩åï¼åé³ä¸ºâsparkleâãï¼SPARQLæ©äºCypherï¼å¹¶ä¸ç±äºCypherç模å¼å¹é
åé´äºSPARQLï¼è¿ä½¿å¾å®ä»¬çèµ·æ¥é常ç¸ä¼¼ã37ãã
ä¸ä¹åç¸åçæ¥è¯¢ - æ¥æ¾ä»ç¾å½è½¬ç§»å°æ¬§æ´²ç人 - 使ç¨SPARQLæ¯ä½¿ç¨Cypherçè³æ´ä¸ºç®æ´ï¼åè§[ä¾2-9]()ï¼ã
**ä¾2-9 ä¸ç¤ºä¾2-4ç¸åçæ¥è¯¢ï¼ç¨SPARQL表示**
```sparql
PREFIX :
SELECT ?personName WHERE {
?person :name ?personName.
?person :bornIn / :within* / :name "United States".
?person :livesIn / :within* / :name "Europe".
}
```
ç»æé常ç¸ä¼¼ã以ä¸ä¸¤ä¸ªè¡¨è¾¾å¼æ¯çä»·çï¼SPARQLä¸çåé以é®å·å¼å¤´ï¼ï¼
```
(person) -[:BORN_IN]-> () -[:WITHIN*0..]-> (location) # Cypher
?person :bornIn / :within* ?location. # SPARQL
```
å 为RDFä¸åºåå±æ§åè¾¹ï¼èåªæ¯å°å®ä»¬ä½ä¸ºè°è¯ï¼æ以å¯ä»¥ä½¿ç¨ç¸åçè¯æ³æ¥å¹é
å±æ§ãå¨ä¸é¢ç表达å¼ä¸ï¼åé`usa`被ç»å®å°ä»»æå
·æå¼ä¸ºå符串`"United States"`ç`name`å±æ§ç顶ç¹ï¼
```
(usa {name:'United States'}) # Cypher
?usa :name "United States". # SPARQL
```
SPARQLæ¯ä¸ç§å¾å¥½çæ¥è¯¢è¯è¨ââåªæè¯ä¹ç½ä»æªå®ç°ï¼å®ä»ç¶å¯ä»¥æ为ä¸ç§åºç¨ç¨åºå
é¨ä½¿ç¨ç强大工å
·ã
> #### å¾å½¢æ°æ®åºä¸ç½ç»æ¨¡åç¸æ¯è¾
>
> å¨â[ææ¡£æ°æ®åºæ¯å¦å¨éè¹è¦è¾ï¼](#ææ¡£æ°æ®åºæ¯å¦å¨éè¹è¦è¾ï¼)âä¸ï¼æ们讨论äºCODASYLåå
³ç³»æ¨¡åå¦ä½ç«ç¸è§£å³IMSä¸çå¤å¯¹å¤å
³ç³»é®é¢ãä¹ä¸çï¼CODASYLçç½ç»æ¨¡åçèµ·æ¥ä¸å¾æ¨¡åç¸ä¼¼ãCODASYLæ¯å¦æ¯å¾å½¢æ°æ®åºç第äºä¸ªåç§ï¼
>
> ä¸ï¼ä»ä»¬å¨å 个éè¦æ¹é¢ææä¸åï¼
>
> * å¨CODASYLä¸ï¼æ°æ®åºæä¸ä¸ªæ¨¡å¼ï¼ç¨äºæå®åªç§è®°å½ç±»åå¯ä»¥åµå¥å¨å
¶ä»è®°å½ç±»åä¸ãå¨å¾å½¢æ°æ®åºä¸ï¼ä¸åå¨è¿æ ·çéå¶ï¼ä»»ä½é¡¶ç¹é½å¯ä»¥å
·æå°å
¶ä»ä»»ä½é¡¶ç¹çè¾¹ãè¿ä¸ºåºç¨ç¨åºéåºä¸æååçéæ±æä¾äºæ´å¤§ççµæ´»æ§ã
> * å¨CODASYLä¸ï¼è¾¾å°ç¹å®è®°å½çå¯ä¸æ¹æ³æ¯éåå
¶ä¸çä¸ä¸ªè®¿é®è·¯å¾ãå¨å¾å½¢æ°æ®åºä¸ï¼å¯ä»¥éè¿å
¶å¯ä¸IDç´æ¥å¼ç¨ä»»ä½é¡¶ç¹ï¼ä¹å¯ä»¥ä½¿ç¨ç´¢å¼æ¥æ¥æ¾å
·æç¹å®å¼ç顶ç¹ã
> * å¨CODASYLï¼è®°å½çåç»æ¯ä¸ä¸ªæåºéåï¼æ以æ°æ®åºç人ä¸å¾ä¸ç»´ææåºï¼è¿ä¼å½±ååå¨å¸å±ï¼ï¼å¹¶ä¸æå
¥æ°è®°å½å°æ°æ®åºçåºç¨ç¨åºä¸å¾ä¸æ
å¿çæ°è®°å½å¨è¿äºéåä¸çä½ç½®ãå¨å¾å½¢æ°æ®åºä¸ï¼é¡¶ç¹åè¾¹ä¸æ¯æåºçï¼åªè½å¨æ¥è¯¢æ¶å¯¹ç»æè¿è¡æåºï¼ã
> * å¨CODASYLä¸ï¼æææ¥è¯¢é½æ¯å½ä»¤å¼çï¼é¾ä»¥ç¼åï¼å¹¶ä¸å¾å®¹æå æ¶æä¸çååèåå°ç ´åãå¨å¾å½¢æ°æ®åºä¸ï¼å¦æéè¦ï¼å¯ä»¥å¨å½ä»¤å¼ä»£ç ä¸ç¼åéåï¼ä½å¤§å¤æ°å¾å½¢æ°æ®åºä¹æ¯æé«çº§å£°æå¼æ¥è¯¢è¯è¨ï¼å¦CypheræSPARQLã
>
>
### åºç¡ï¼Datalog
**Datalog**æ¯æ¯SPARQLæCypheræ´å¤èçè¯è¨ï¼å¨20ä¸çºª80年代被å¦è
广æ³ç 究ã44,45,46ããå®å¨è½¯ä»¶å·¥ç¨å¸ä¸ä¸å¤ªç¥åï¼ä½æ¯å®æ¯éè¦çï¼å 为å®ä¸ºä»¥åçæ¥è¯¢è¯è¨æä¾äºåºç¡ã
å¨å®è·µä¸ï¼Datalog被ç¨äºå°æ°çæ°æ®ç³»ç»ä¸ï¼ä¾å¦ï¼å®æ¯Datomic ã40ãçæ¥è¯¢è¯è¨ï¼Cascalog ã47ãæ¯ä¸ç§ç¨äºæ¥è¯¢Hadoop大æ°æ®éçDatalogå®ç°[^viii]ã
[^viii]: DatomicåCascalog使ç¨DatalogçClojure S表达å¼è¯æ³ãå¨ä¸é¢çä¾åä¸ä½¿ç¨äºä¸ä¸ªæ´å®¹æé
读çPrologè¯æ³ï¼ä½ä¸¤è
没æä»»ä½åè½å·®å¼ã
Datalogçæ°æ®æ¨¡å类似äºä¸å
ç»æ¨¡å¼ï¼ä½è¿è¡äºä¸ç¹æ³åãæä¸å
ç»åæ**è°è¯**ï¼**主è¯ï¼å®¾è¯**ï¼ï¼èä¸æ¯åä¸å
è¯ï¼**主è¯ï¼è°è¯ï¼å®¾è¯**ï¼ã[ä¾2-10]()æ¾ç¤ºäºå¦ä½ç¨Datalogåå
¥æ们çä¾åä¸çæ°æ®ã
**ä¾2-10 ç¨Datalogæ¥è¡¨ç¤ºå¾2-5ä¸çæ°æ®åé**
```prolog
name(namerica, 'North America').
type(namerica, continent).
name(usa, 'United States').
type(usa, country).
within(usa, namerica).
name(idaho, 'Idaho').
type(idaho, state).
within(idaho, usa).
name(lucy, 'Lucy').
born_in(lucy, idaho).
```
æ¢ç¶å·²ç»å®ä¹äºæ°æ®ï¼æ们å¯ä»¥åä¹åä¸æ ·ç¼åç¸åçæ¥è¯¢ï¼å¦[ä¾2-11]()æ示ãå®çèµ·æ¥æç¹ä¸åäºCypheræSPARQLççä»·ç©ï¼ä½æ¯è¯·ä¸è¦æ¾å¼å®ãDatalogæ¯Prologçä¸ä¸ªåéï¼å¦æä½ å¦è¿è®¡ç®æºç§å¦ï¼ä½ å¯è½å·²ç»è§è¿ã
**ä¾2-11 ä¸ç¤ºä¾2-4ç¸åçæ¥è¯¢ï¼ç¨Datalog表示**
```
within_recursive(Location, Name) :- name(Location, Name). /* Rule 1 */
within_recursive(Location, Name) :- within(Location, Via), /* Rule 2 */
within_recursive(Via, Name).
migrated(Name, BornIn, LivingIn) :- name(Person, Name), /* Rule 3 */
born_in(Person, BornLoc),
within_recursive(BornLoc, BornIn),
lives_in(Person, LivingLoc),
within_recursive(LivingLoc, LivingIn).
?- migrated(Who, 'United States', 'Europe'). /* Who = 'Lucy'. */
```
CypheråSPARQL使ç¨SELECTç«å³è·³è½¬ï¼ä½æ¯Datalogä¸æ¬¡åªè¿è¡ä¸å°æ¥ãæ们å®ä¹**è§å**ï¼ä»¥å°æ°è°è¯åè¯æ°æ®åºï¼å¨è¿éï¼æ们å®ä¹äºä¸¤ä¸ªæ°çè°è¯ï¼`within_recursive`å`migrated`ãè¿äºè°è¯ä¸æ¯åå¨å¨æ°æ®åºä¸çä¸å
ç»ä¸ï¼èæ¯å®ä»¬æ¯ä»æ°æ®æå
¶ä»è§åæ´¾çèæ¥çãè§åå¯ä»¥å¼ç¨å
¶ä»è§åï¼å°±åå½æ°å¯ä»¥è°ç¨å
¶ä»å½æ°æè
éå½å°è°ç¨èªå·±ä¸æ ·ãåè¿æ ·ï¼å¤æçæ¥è¯¢å¯ä»¥ä¸æ¬¡æ建å
¶ä¸çä¸å°åã
å¨è§åä¸ï¼ä»¥å¤§ååæ¯å¼å¤´çåè¯æ¯åéï¼è°è¯åç¨CypheråSPARQLçæ¹å¼ä¸æ ·æ¥å¹é
ãä¾å¦ï¼`name(Location, Name)`éè¿åéç»å®`Location = namerica`å`Name ='North America'`å¯ä»¥å¹é
ä¸å
ç»`name(namerica, 'North America')`ã
è¦æ¯ç³»ç»å¯ä»¥å¨`:-` æä½ç¬¦çå³ä¾§æ¾å°ä¸ææè°è¯çä¸ä¸ªå¹é
ï¼å°±è¿ç¨è¯¥è§åãå½è§åè¿ç¨æ¶ï¼å°±å¥½åéè¿`:-`ç左侧å°å
¶æ·»å å°æ°æ®åºï¼å°åéæ¿æ¢æå®ä»¬å¹é
çå¼ï¼ã
å æ¤ï¼ä¸ç§å¯è½çåºç¨è§åçæ¹å¼æ¯ï¼
1. æ°æ®åºåå¨`name(namerica, 'North America')`ï¼æ
è¿ç¨è§å1ãå®çæ`within_recursive(namerica, 'North America')`ã
2. æ°æ®åºåå¨`within(usa, namerica)`ï¼å¨ä¸ä¸æ¥éª¤ä¸çæ`within_recursive(namerica, 'North America')`ï¼æ
è¿ç¨è§å2ãå®ä¼äº§ç`within_recursive(usa, 'North America')`ã
3. æ°æ®åºåå¨`within(idaho, usa)`ï¼å¨ä¸ä¸æ¥çæ`within_recursive(usa, 'North America')`ï¼æ
è¿ç¨è§å2ãå®äº§ç`within_recursive(idaho, 'North America')`ã
éè¿éå¤åºç¨è§å1å2ï¼`within_recursive`è°è¯å¯ä»¥åè¯æ们å¨æ°æ®åºä¸å
å«åç¾ï¼æä»»ä½å
¶ä»ä½ç½®å称ï¼çææä½ç½®ãè¿ä¸ªè¿ç¨å¦[å¾2-6](img/fig2-6.png)æ示ã
![](img/fig2-6.png)
**å¾2-6 使ç¨ç¤ºä¾2-11ä¸çDatalogè§åæ¥ç¡®å®ç±è¾¾è·å·å¨åç¾ã**
ç°å¨è§å3å¯ä»¥æ¾å°åºçå¨æ个å°æ¹`BornIn`ç人ï¼å¹¶ä½å¨æ个å°æ¹`LivingIn`ãéè¿æ¥è¯¢`BornIn ='United States'`å`LivingIn ='Europe'`ï¼å¹¶å°æ¤äººä½ä¸ºåé`Who`ï¼è®©Datalogç³»ç»æ¾åºåé`Who`ä¼åºç°åªäºå¼ãå æ¤ï¼æåå¾å°äºä¸æ©å
çCypheråSPARQLæ¥è¯¢ç¸åççæ¡ã
ç¸å¯¹äºæ¬ç« 讨论çå
¶ä»æ¥è¯¢è¯è¨ï¼æ们éè¦éåä¸åçæç»´æ¹å¼æ¥æèDatalogæ¹æ³ï¼ä½è¿æ¯ä¸ç§é常强大çæ¹æ³ï¼å 为è§åå¯ä»¥å¨ä¸åçæ¥è¯¢ä¸è¿è¡ç»ååéç¨ãè½ç¶å¯¹äºç®åçä¸æ¬¡æ§æ¥è¯¢ï¼æ¾å¾ä¸å¤ªæ¹ä¾¿ï¼ä½æ¯å®å¯ä»¥æ´å¥½å°å¤çæ°æ®å¾å¤æçæ
åµã
## æ¬ç« å°ç»
æ°æ®æ¨¡åæ¯ä¸ä¸ªå·¨å¤§ç课é¢ï¼å¨æ¬ç« ä¸ï¼æ们快éæµè§äºåç§ä¸åç模åãæ们没æ足å¤ç空é´æ¥è¯¦ç»ä»ç»æ¯ä¸ªæ¨¡åçç»èï¼ä½æ¯å¸æè¿ä¸ªæ¦è¿°è¶³ä»¥æ¿èµ·ä½ çå
´è¶£ï¼ä»¥æ´å¤å°äºè§£æéåä½ çåºç¨éæ±ç模åã
å¨åå²ä¸ï¼æ°æ®æå¼å§è¢«è¡¨ç¤ºä¸ºä¸æ£µå¤§æ ï¼å±æ¬¡æ°æ®æ¨¡åï¼ï¼ä½æ¯è¿ä¸å©äºè¡¨ç¤ºå¤å¯¹å¤çå
³ç³»ï¼æ以åæäºå
³ç³»æ¨¡åæ¥è§£å³è¿ä¸ªé®é¢ãæè¿ï¼å¼å人ååç°ä¸äºåºç¨ç¨åºä¹ä¸éåéç¨å
³ç³»æ¨¡åãæ°çéå
³ç³»åâNoSQLâæ°æ®åå¨å¨ä¸¤ä¸ªä¸»è¦æ¹åä¸åå¨åæ§ï¼
1. **ææ¡£æ°æ®åº**çåºç¨åºæ¯æ¯ï¼æ°æ®é常æ¯èªæå
å«çï¼èä¸ææ¡£ä¹é´çå
³ç³»é常ç¨å°ã
2. **å¾å½¢æ°æ®åº**ç¨äºç¸åçåºæ¯ï¼ä»»æäºç©é½å¯è½ä¸ä»»ä½äºç©ç¸å
³èã
è¿ä¸ç§æ¨¡åï¼ææ¡£ï¼å
³ç³»åå¾å½¢ï¼å¨ä»å¤©é½è¢«å¹¿æ³ä½¿ç¨ï¼å¹¶ä¸å¨åèªçé¢åé½åæ¥å¾å¥½ãä¸ä¸ªæ¨¡åå¯ä»¥ç¨å¦ä¸ä¸ªæ¨¡åæ¥æ¨¡æ â ä¾å¦ï¼å¾æ°æ®å¯ä»¥å¨å
³ç³»æ°æ®åºä¸è¡¨ç¤º â ä½ç»æå¾å¾æ¯ç³ç³çãè¿å°±æ¯ä¸ºä»ä¹æ们æçé对ä¸åç®ççä¸åç³»ç»ï¼èä¸æ¯ä¸ä¸ªåä¸çä¸è½è§£å³æ¹æ¡ã
ææ¡£æ°æ®åºåå¾æ°æ®åºæä¸ä¸ªå
±åç¹ï¼é£å°±æ¯å®ä»¬é常ä¸ä¼ä¸ºåå¨çæ°æ®å¼ºå¶ä¸ä¸ªæ¨¡å¼ï¼è¿å¯ä»¥ä½¿åºç¨ç¨åºæ´å®¹æéåºä¸æååçéæ±ãä½æ¯åºç¨ç¨åºå¾å¯è½ä»ä¼åå®æ°æ®å
·æä¸å®çç»æï¼è¿åªæ¯æ¨¡å¼æ¯æç¡®çï¼åå
¥æ¶å¼ºå¶ï¼è¿æ¯éå«çï¼è¯»åæ¶å¤çï¼çé®é¢ã
æ¯ä¸ªæ°æ®æ¨¡åé½å
·æåèªçæ¥è¯¢è¯è¨ææ¡æ¶ï¼æ们讨论äºå 个ä¾åï¼SQLï¼MapReduceï¼MongoDBçèå管éï¼Cypherï¼SPARQLåDatalogãæ们ä¹è°å°äºCSSåXSL/XPathï¼å®ä»¬ä¸æ¯æ°æ®åºæ¥è¯¢è¯è¨ï¼èå
å«æ趣çç¸ä¼¼ä¹å¤ã
è½ç¶æ们已ç»è¦çäºå¾å¤å±é¢ï¼ä½ä»ç¶æ许å¤æ°æ®æ¨¡å没ææå°ã举å 个ç®åçä¾åï¼
* 使ç¨åºå ç»æ°æ®çç 究人åé常éè¦æ§è¡**åºåç¸ä¼¼æ§æç´¢**ï¼è¿æå³çéè¦ä¸ä¸ªå¾é¿çå符串ï¼ä»£è¡¨ä¸ä¸ªDNAååï¼ï¼å¹¶å¨ä¸ä¸ªæ¥æ类似ä½ä¸å®å
¨ç¸åçå符串ç大åæ°æ®åºä¸å¯»æ¾å¹é
ãè¿éææè¿°çæ°æ®åºé½ä¸è½å¤çè¿ç§ç¨æ³ï¼è¿å°±æ¯ä¸ºä»ä¹ç 究人åç¼åäºåGenBankè¿æ ·çä¸é¨çåºå ç»æ°æ®åºè½¯ä»¶çåå ã48ãã
* ç²åç©çå¦å®¶æ°åå¹´æ¥ä¸ç´å¨è¿è¡å¤§æ°æ®ç±»åç大è§æ¨¡æ°æ®åæï¼å大å强å对ææºï¼LHCï¼è¿æ ·ç项ç®ç°å¨å¯ä»¥å·¥ä½å¨æ°ç¾äº¿å
åèçèå´å
ï¼å¨è¿æ ·çè§æ¨¡ä¸ï¼éè¦å®å¶è§£å³æ¹æ¡æ¥é»æ¢ç¡¬ä»¶ææ¬ç失æ§ã49ãã
* **å
¨ææç´¢**å¯ä»¥è¯´æ¯ä¸ç§ç»å¸¸ä¸æ°æ®åºä¸èµ·ä½¿ç¨çæ°æ®æ¨¡åãä¿¡æ¯æ£ç´¢æ¯ä¸ä¸ªå¾å¤§çä¸ä¸è¯¾é¢ï¼æ们ä¸ä¼å¨æ¬ä¹¦ä¸è¯¦ç»ä»ç»ï¼ä½æ¯æ们å°å¨ç¬¬ä¸ç« å第ä¸ç« ä¸ä»ç»æ索索å¼ã
让æ们ææ¶å°å
¶æ¾å¨ä¸è¾¹ãå¨[ä¸ä¸ç« ](ch3.md)ä¸ï¼æ们å°è®¨è®ºå¨**å®ç°**æ¬ç« æè¿°çæ°æ®æ¨¡åæ¶ä¼éå°çä¸äºæè¡¡ã
## åèæç®
1. Edgar F. Codd: â[A Relational Model of Data for Large Shared Data Banks](https://www.seas.upenn.edu/~zives/03f/cis550/codd.pdf),â *Communications of the ACM*, volume 13, number 6, pages 377â387, June 1970. [doi:10.1145/362384.362685](http://dx.doi.org/10.1145/362384.362685)
1. Michael Stonebraker and Joseph M. Hellerstein: â[What Goes Around Comes Around](http://mitpress2.mit.edu/books/chapters/0262693143chapm1.pdf),â
in *Readings in Database Systems*, 4th edition, MIT Press, pages 2â41, 2005. ISBN: 978-0-262-69314-1
1. Pramod J. Sadalage and Martin Fowler: *NoSQL Distilled*. Addison-Wesley, August 2012. ISBN:
978-0-321-82662-6
1. Eric Evans: â[NoSQL: What's in a Name?](http://blog.sym-link.com/2009/10/30/nosql_whats_in_a_name.html),â *blog.sym-link.com*, October 30, 2009.
1. James Phillips: â[Surprises in Our NoSQL Adoption Survey](http://blog.couchbase.com/nosql-adoption-survey-surprises),â *blog.couchbase.com*, February 8, 2012.
1. Michael Wagner: *SQL/XML:2006 â Evaluierung der Standardkonformität ausgewählter Datenbanksysteme*. Diplomica Verlag, Hamburg, 2010. ISBN: 978-3-836-64609-3
1. â[XML Data in SQL Server](http://technet.microsoft.com/en-us/library/bb522446.aspx),â SQL Server 2012 documentation, *technet.microsoft.com*, 2013.
1. â[PostgreSQL 9.3.1 Documentation](http://www.postgresql.org/docs/9.3/static/index.html),â The PostgreSQL Global Development Group, 2013.
1. â[The MongoDB 2.4 Manual](http://docs.mongodb.org/manual/),â MongoDB, Inc., 2013.
1. â[RethinkDB 1.11 Documentation](http://www.rethinkdb.com/docs/),â *rethinkdb.com*, 2013.
1. â[Apache CouchDB 1.6 Documentation](http://docs.couchdb.org/en/latest/),â *docs.couchdb.org*, 2014.
1. Lin Qiao, Kapil Surlaker, Shirshanka Das, et al.: â[On Brewing Fresh Espresso: LinkedInâs Distributed Data Serving Platform](http://www.slideshare.net/amywtang/espresso-20952131),â at *ACM International Conference on Management of Data* (SIGMOD), June 2013.
1. Rick Long, Mark Harrington, Robert Hain, and Geoff Nicholls: *IMS Primer*. IBM Redbook SG24-5352-00, IBM International Technical Support Organization, January 2000.
1. Stephen D. Bartlett: â[IBMâs IMSâMyths, Realities, and Opportunities](ftp://public.dhe.ibm.com/software/data/ims/pdf/TCG2013015LI.pdf),â The Clipper Group Navigator, TCG2013015LI, July 2013.
1. Sarah Mei: â[Why You Should Never Use MongoDB](http://www.sarahmei.com/blog/2013/11/11/why-you-should-never-use-mongodb/),â *sarahmei.com*, November 11, 2013.
1. J. S. Knowles and D. M. R. Bell: âThe CODASYL Model,â in *DatabasesâRole and Structure: An Advanced Course*, edited by P. M. Stocker, P. M. D. Gray, and M. P. Atkinson, pages 19â56, Cambridge University Press, 1984. ISBN: 978-0-521-25430-4
1. Charles W. Bachman: â[The Programmer as Navigator](http://dl.acm.org/citation.cfm?id=362534),â *Communications of the ACM*, volume 16, number 11, pages 653â658, November 1973. [doi:10.1145/355611.362534](http://dx.doi.org/10.1145/355611.362534)
1. Joseph M. Hellerstein, Michael Stonebraker, and James Hamilton: â[Architecture of a Database System](http://db.cs.berkeley.edu/papers/fntdb07-architecture.pdf),â
*Foundations and Trends in Databases*, volume 1, number 2, pages 141â259, November 2007. [doi:10.1561/1900000002](http://dx.doi.org/10.1561/1900000002)
1. Sandeep Parikh and Kelly Stirman: â[Schema Design for Time Series Data in MongoDB](http://blog.mongodb.org/post/65517193370/schema-design-for-time-series-data-in-mongodb),â *blog.mongodb.org*, October 30, 2013.
1. Martin Fowler: â[Schemaless Data Structures](http://martinfowler.com/articles/schemaless/),â *martinfowler.com*, January 7, 2013.
1. Amr Awadallah: â[Schema-on-Read vs. Schema-on-Write](http://www.slideshare.net/awadallah/schemaonread-vs-schemaonwrite),â at *Berkeley EECS RAD Lab Retreat*, Santa Cruz, CA, May 2009.
1. Martin Odersky: â[The Trouble with Types](http://www.infoq.com/presentations/data-types-issues),â at *Strange Loop*, September 2013.
1. Conrad Irwin: â[MongoDBâConfessions of a PostgreSQL Lover](https://speakerdeck.com/conradirwin/mongodb-confessions-of-a-postgresql-lover),â at *HTML5DevConf*, October 2013.
1. â[Percona Toolkit Documentation: pt-online-schema-change](http://www.percona.com/doc/percona-toolkit/2.2/pt-online-schema-change.html),â Percona Ireland Ltd., 2013.
1. Rany Keddo, Tobias Bielohlawek, and Tobias Schmidt: â[Large Hadron Migrator](https://github.com/soundcloud/lhm),â SoundCloud, 2013. Shlomi Noach:
â[gh-ost: GitHub's Online Schema Migration Tool for MySQL](http://githubengineering.com/gh-ost-github-s-online-migration-tool-for-mysql/),â *githubengineering.com*, August 1, 2016.
1. James C. Corbett, Jeffrey Dean, Michael Epstein, et al.: â[Spanner: Googleâs Globally-Distributed Database](http://research.google.com/archive/spanner.html),â at *10th USENIX Symposium on Operating System Design and Implementation* (OSDI),
October 2012.
1. Donald K. Burleson: â[Reduce I/O with Oracle Cluster Tables](http://www.dba-oracle.com/oracle_tip_hash_index_cluster_table.htm),â *dba-oracle.com*.
1. Fay Chang, Jeffrey Dean, Sanjay Ghemawat, et al.: â[Bigtable: A Distributed Storage System for Structured Data](http://research.google.com/archive/bigtable.html),â at *7th USENIX Symposium on Operating System Design and Implementation* (OSDI), November 2006.
1. Bobbie J. Cochrane and Kathy A. McKnight: â[DB2 JSON Capabilities, Part 1: Introduction to DB2 JSON](http://www.ibm.com/developerworks/data/library/techarticle/dm-1306nosqlforjson1/),â IBM developerWorks, June 20, 2013.
1. Herb Sutter: â[The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software](http://www.gotw.ca/publications/concurrency-ddj.htm),â *Dr. Dobb's Journal*, volume 30, number 3, pages 202-210, March 2005.
1. Joseph M. Hellerstein: â[The Declarative Imperative: Experiences and Conjectures in Distributed Logic](http://www.eecs.berkeley.edu/Pubs/TechRpts/2010/EECS-2010-90.pdf),â Electrical Engineering and Computer Sciences, University of California at Berkeley, Tech report UCB/EECS-2010-90, June 2010.
1. Jeffrey Dean and Sanjay Ghemawat: â[MapReduce: Simplified Data Processing on Large Clusters](http://research.google.com/archive/mapreduce.html),â at *6th USENIX Symposium on Operating System Design and Implementation* (OSDI), December 2004.
1. Craig Kerstiens: â[JavaScript in Your Postgres](https://blog.heroku.com/javascript_in_your_postgres),â *blog.heroku.com*, June 5, 2013.
1. Nathan Bronson, Zach Amsden, George Cabrera, et al.: â[TAO: Facebookâs Distributed Data Store for the Social Graph](https://www.usenix.org/conference/atc13/technical-sessions/presentation/bronson),â at *USENIX Annual Technical Conference* (USENIX ATC), June 2013.
1. â[Apache TinkerPop3.2.3 Documentation](http://tinkerpop.apache.org/docs/3.2.3/reference/),â *tinkerpop.apache.org*, October 2016.
1. â[The Neo4j Manual v2.0.0](http://docs.neo4j.org/chunked/2.0.0/index.html),â Neo Technology, 2013. Emil Eifrem: [Twitter correspondence](https://twitter.com/emileifrem/status/419107961512804352), January 3, 2014.
1. David Beckett and Tim Berners-Lee: â[Turtle â Terse RDF Triple Language](http://www.w3.org/TeamSubmission/turtle/),â W3C Team Submission, March 28, 2011.
1. â[Datomic Development Resources](http://docs.datomic.com/),â Metadata Partners, LLC, 2013. W3C RDF Working Group: â[Resource Description Framework (RDF)](http://www.w3.org/RDF/),â *w3.org*, 10 February 2004.
1. â[Apache Jena](http://jena.apache.org/),â Apache Software Foundation.
1. Steve Harris, Andy Seaborne, and Eric Prud'hommeaux: â[SPARQL 1.1 Query Language](http://www.w3.org/TR/sparql11-query/),â
W3C Recommendation, March 2013.
1. Todd J. Green, Shan Shan Huang, Boon Thau Loo, and Wenchao Zhou: â[Datalog and Recursive Query Processing](http://blogs.evergreen.edu/sosw/files/2014/04/Green-Vol5-DBS-017.pdf),â *Foundations and Trends in Databases*, volume 5, number 2, pages 105â195, November 2013. [doi:10.1561/1900000017](http://dx.doi.org/10.1561/1900000017)
1. Stefano Ceri, Georg Gottlob, and Letizia Tanca: â[What You Always Wanted to Know About Datalog (And Never Dared to Ask)](https://www.researchgate.net/profile/Letizia_Tanca/publication/3296132_What_you_always_wanted_to_know_about_Datalog_and_never_dared_to_ask/links/0fcfd50ca2d20473ca000000.pdf),â *IEEE Transactions on Knowledge and Data Engineering*, volume 1, number 1, pages 146â166, March 1989. [doi:10.1109/69.43410](http://dx.doi.org/10.1109/69.43410)
1. Serge Abiteboul, Richard Hull, and Victor Vianu: *Foundations of Databases*. Addison-Wesley, 1995. ISBN: 978-0-201-53771-0, available online at *webdam.inria.fr/Alice*
1. Nathan Marz: â[Cascalog](http://cascalog.org/)," *cascalog.org*. Dennis A. Benson, Ilene Karsch-Mizrachi, David J. Lipman, et al.:
â[GenBank](http://nar.oxfordjournals.org/content/36/suppl_1/D25.full-text-lowres.pdf),â *Nucleic Acids Research*, volume 36, Database issue, pages D25âD30, December 2007. [doi:10.1093/nar/gkm929](http://dx.doi.org/10.1093/nar/gkm929)
1. Fons Rademakers: â[ROOT for Big Data Analysis](http://indico.cern.ch/getFile.py/access?contribId=13&resId=0&materialId=slides&confId=246453),â at *Workshop on the Future of Big Data Management*,
London, UK, June 2013.
------
| ä¸ä¸ç« | ç®å½ | ä¸ä¸ç« |
| -------------------------------------------- | ------------------------------- | ---------------------------- |
| [第ä¸ç« ï¼å¯é æ§ãå¯ä¼¸ç¼©æ§ãå¯ç»´æ¤æ§](ch1.md) | [设计æ°æ®å¯éååºç¨](README.md) | [第ä¸ç« ï¼åå¨ä¸æ£ç´¢](ch3.md) |