IT��ά������������ҵ��ֵ��
�й�IT��ά����ҳ | ��Ѷ���� | ��ά���� | ��Ϣ��ȫ | CIO�ӽ� | �Ƽ��� | ��Ѱ��� | ��ά��Դ | ר��߻� | ֪ʶ�� | ��̳

һ���µ�˼ά��ʽ��NoSQL���ݽ�ģ

2010��07��29��
����/����

��ϵ���ݿ��Ѿ�ͳ�����ݴ洢30 �����ˣ�������ģʽ����NoSQL�����ݿ�������б����仯���ڷ��������� RDBMS Ϊ�ڴ�ͳ�Ŀͻ��˷������ܹ��д洢�����ṩ��һ����ʵ�Ļ����������������ɵأ�����˵أ���չ������ڵ㡣�ڸ߶ȿ������� Web Ӧ�ó��򣨱��� Facebook �� Twitter����ʱ��������һ���dz����ҵ����㡣

���ܹ�ϵ���ݿ������������������ǵ������������ݿ��𣿣����ܽ�������������� �⣬NoSQL ���ݿ⣨���� Google �� Bigtable �� Amazon �� SimpleDB��ȴ��Ϊ�� Web �ĸ߿������������ֱ����Ӧ�����𡣱����ϣ�NoSQL ������һ��ɱ�������ɱ��Ӧ�ó��� —���� Web 2.0 ���ݱ䣬Web Ӧ�ó��򿪷���Ա���ܻ��������࣬�����Ǹ���������Ӧ�ó���

������ Java ���� 2.0 �У��ҽ�����������ģʽ���ݽ�ģ�����Ǿ�����ϵ˼άģʽѵ�������࿪����Աʹ�� NoSQL ����Ҫ�ϰ��������˽⵽����һ����ģ�ͣ������ǹ�ϵģ�ͣ������Ǽ����ĸı�Ĺؼ��������ʹ�� Bigtable�����ҵ�ʾ����ʾ���������Խ��� Gaelyk��Google App Engine ��һ�������������չ��

NoSQL��һ���µ�˼ά��ʽ��

��������Ա̸�۷ǹ�ϵ�� NoSQL ���ݿ�ʱ�������ᵽ�ĵ�һ������������Ҫ�ı�˼ά��ʽ������Ϊ����ʵ����ȡ�������ij�ʼ���ݽ�ģ�����������ϰ��ͨ�����Ƚ�ģ���ݿ�ṹ��������ȷ������ �������ϵ�������Ӧ�ó�����ôʹ��һ����ģʽ���ݴ洢������ Bigtable�����������ݽ�ģ����Ҫ������˼���������·�ʽ�����ǣ����������ģ�Ϳ�ʼ�������Ӧ�ó�����ô Bigtable ����ģʽ�ṹ������������Ȼ��

�ǹ�ϵ���ݴ洢û�����ӱ�������������û������������������������͵ļ���һ�ָ���ɢ�� ��ʽ���֣�����ˣ���������Խ���ϵ��ģ��Ϊһ�� NoSQL ���ݿ��е����ݽ�ģ�Ļ�������ô�����������ʧ�ܸ��ա�����ģ�Ϳ�ʼ��ʹ�����ü򵥣�ʵ���ϣ����Ѿ����֣���ģ���µ���ģʽ�ṹ��������������»����� ����

�ӹ�ϵ����ģ��Ǩ�Ƶ���ģʽ����ģ�͵���Ը��ӳ̶�ȡ�������ķ����������ӻ��ڹ�ϵ����ƿ� ʼ���Ǵӻ��������ƿ�ʼ������Ǩ�Ƶ� CouchDB �� Bigtable ���������ݿ�ʱ���� ��ȷ��ɥʧ Hibernate���������ڣ������ij���ij־ô洢ƽ̨��˳���о�����һ���棬��ȴӵ���ܹ����Թ������� “�̵�Ч��”���ڴ˹����У����������˽���ģʽ���ݴ洢��

ʵ��͹�ϵ

��ģʽ���ݴ洢����������ʹ�ö����������ģ�͵�����ԣ�Grails �����Ľ��µĿ���Զ�֧����������ԣ���������һ�������ǽ�������ӳ�䵽�ײ����ݴ洢������ʹ�� Google App Engine ʱ�ټ򵥲����ˡ�

������ “Java ���� 2.0����� Google App Engine �� Gaelyk” �У��ҽ����� Gaelyk —— һ������ Groovy �Ŀ�ܣ��ÿ��������ʹ�� Google �ĵײ����ݴ洢����ƪ���µ���Ҫ���ֹ�ע������� Google �� Entity���������ʾ����������ƪ���£���չʾ����ʵ������� Gaelyk �й�����

�嵥1. ʹ�� Entity �Ķ���־ô洢

  1. def ticket = new Entity("ticket")
  2. ticket.officer = params.officer
  3. ticket.license = params.plate
  4. ticket.issuseDate = offensedate
  5. ticket.location = params.location
  6. ticket.notes = params.notes
  7. ticket.offense = params.offense

���ֶ���־ô洢��������Ч�������׿����������Ƶ��ʹ��Ʊ��ʵ�� —���磬��������ڸ��� servlet �д���������ң����ǣ���ô���ַ�������������ᷳ��ʹ��һ������ servlet���� Groovlet����Ϊ��������Щ������������һЩ������һ�ָ���Ȼ��ѡ��——�ҽ��Ժ�չʾ——���ǽ�ģһ�� Ticket����

���ر���

�Ҳ����ظ� Gaelyk ����е��Ǹ�Ʊ��ʾ�����෴��Ϊ�������ʸУ��ҽ��ڱ�����ʹ��һ���������⣬������һ��Ӧ�ó�����չʾ�������۵ļ�����

��ͼ 1 �е� “��Զ�” ͼ����ʾ��һ�� Raceӵ�ж�� Runner��һ�� Runner�������ڶ�� Race��

ͼ1. �����Ͳ�����

�����Ҫʹ��һ����ϵ���ṹ����������ϵ��������Ҫ 3 �������� 3 ����������һ�� “��Զ�” ��ϵ�����ӱ��������Ҳ��ؾ����ڹ�ϵ����ģ�͡��෴���ҽ�ʹ�� Gaelyk���� Groovy ���룩����� “��Զ�” ��ϵӳ�䵽 Google ��� Google App Engine �� Bigtable ������ʵ�ϣ�Gaelyk ������ Entity���� Map����ʹ��ӳ������൱�򵥡�

��ģʽ���ݴ洢�ĺô�֮һ����������֪���������飬Ҳ����˵����ʹ�ù�ϵ���ݿ�ܹ���ȣ��� �Ը����ɵ���Ӧ�仯����ע�⣬�Ҳ��ǰ�ʾ���ܸ��ļܹ�����ֻ��˵�����Ը����ɵ���Ӧ�仯�����Ҳ����㶨���ҵ�������ϵ����� —�ҽ����Ƴٵ� Groovy �Ķ�̬���ԣ�ʵ���ϣ������������������� Google �� Entity������������������෴���ҽ����ҵ�ʱ�仨����ȷ����β��Ҷ��󲢴�����ϵ�ϡ����� NoSQL �͸���������ģʽ���ݴ洢�Ŀ�ܻ�û�����õĹ��ܡ�

Model ����

�ҽ����ȴ���һ�����࣬�������� Entity�����һ��ʵ����Ȼ���ҽ�����һЩ����ӵ��һЩ��̬���ԣ���Щ��̬���Խ�ͨ�� Groovy �ķ���� setProperty�������ӵ���Ӧ�� Entityʵ����setProperty��Զ�����ʵ���ϲ����ڵ��κ��������ó�����á���������������������ţ����õ��ģ�����������ʵ�����к�ͻ� ���ס���

�嵥2չʾ��λ���ҵ�ʾ��Ӧ�ó����һ�� Modelʵ���ĵ�һ�� stab��

�嵥2. һ���򵥵� Model ����

  1. package com.b50.nosql
  2. import com.google.appengine.api.datastore.DatastoreServiceFactory
  3. import com.google.appengine.api.datastore.Entity
  4. abstract class Model {
  5. def entity
  6. static def datastore = DatastoreServiceFactory.datastoreService
  7. public Model(){
  8. super()
  9. }
  10. public Model(params){
  11. this.@entity = new Entity(this.getClass().simpleName)
  12. params.each{ key, val ->
  13. this.setProperty key, val
  14. }
  15. }
  16. def getProperty(String name) {
  17. if(name.equals("id")){
  18. return entity.key.id
  19. }else{
  20. return entity."${name}"
  21. }
  22. }
  23. void setProperty(String name, value) {
  24. entity."${name}" = value
  25. }
  26. def save(){
  27. this.entity.save()
  28. }
  29. }

ע���������ζ���һ�����캯�����ú����������Ե�һ�� Map ——�����ǿ����Ժ����Ӹ��๹�캯�����Ժ��Ҿͻ���ô����������ö��� Web ���ʮ�ַ��㣬��Щ���ͨ�����ôӱ����ύ�IJ�����Gaelyk �� Grails �������IJ�������ط�װ��һ����Ϊ params�Ķ����С�������캯��������� Map�����ÿ�� “�� / ֵ” �Ե��� setProperty������

���һ�� setProperty�����ͻᷢ�� “��” ����Ϊ�ײ� entity���������ƣ�����Ӧ�� “ֵ” �Ǹ� entity��ֵ��

Groovy ����

��ǰ������Groovy �Ķ�̬����������ͨ�� get�� set Property��������Բ����ڵ����Եķ������á��������嵥 2 �е� Model�����಻�ض��������Լ������� —����ֻ�ǽ���һ�����Ե����е���ί�и�����ײ� entity����

�嵥 2 �еĴ���ִ����һЩ�ض��� Groovy �IJ�����ֵ��һ�ᡣ���ȣ�����ͨ����һ������ǰ�渽��һ�� @���ƹ������Եķ������������ұ���Թ��캯���е� entity��������ִ�����������������ҽ����� setProperty�����������ԣ��������ͷ���� setProperty����������ģʽ����Ϊ setProperty�����е� entity�������� null��

��Σ����캯���еĵ��� this.getClass().simpleName������ entity�� “����” —— simpleName���Խ�����һ��������ǰ׺���������ƣ�ע�⣬simpleName��ȷ�Ƕ� getSimpleName�ĵ��ã��� Groovy �����Ҳ�ͨ����Ӧ�� JavaBeans ʽ�ķ������������Է���һ�����ԣ���

�������� id���ԣ���������ļ�������һ�����ã�getProperty���������ܣ��ܹ�ѯ�ʵײ� key�Ի�ȡ���� id���� Google App Engine �У�entities�� key���Խ��Զ����ɡ�

Race ����

���� Race����ܼ򵥣����嵥 3 ��ʾ��

�嵥3. һ�� Race ����

  1. package com.b50.nosql
  2. class Race extends Model {
  3. public Race(params){
  4. super(params)
  5. }
  6. }

��һ������ʹ��һ�в�������һ��������� “�� / ֵ” �Ե� Map��ʵ����ʱ��һ����Ӧ�� entity�����ڴ��д�����Ҫ�־ô洢����ֻ����� save������

�嵥4. ����һ�� Race ʵ�������䱣�浽 GAE �����ݴ洢

  1. import com.b50.nosql.Runner
  2. def iparams = [:]
  3. def formatter = new SimpleDateFormat("MM/dd/yyyy")
  4. def rdate = formatter.parse("04/17/2010")
  5. iparams["name"] = "Charlottesville Marathon"
  6. iparams["date"] = rdate
  7. iparams["distance"] = 26.2 as double
  8. def race = new Race(iparams)
  9. race.save()

�嵥4 ��һ�� Groovlet�����У�һ�� Map����Ϊ iparams������Ϊ���� 3 ������ ——һ�α��������ơ����ں;��롣��ע�⣬�� Groovy �У�һ���հ� Mapͨ�� [:]��������Race��һ����ʵ����������Ȼ��ͨ�� save�����洢���ײ����ݴ洢��

����ͨ�� Google App Engine ����̨���鿴�ײ����ݴ洢��ȷ���ҵ����ݵ�ȷ�������ͼ 2 ��ʾ��

ͼ2. �鿴�´�����Race

���ҳ��򷽷����ɳ־ô洢��ʵ��

�������Ѿ��洢��һ�� Entity��ӵ�в��������������������������������ҿ�������һ�� “���ҳ���” �������ڱ����У��ҽ������ “���ҳ���” ��������Ϊһ���෽����static����������ͨ�����Ʋ�����Щ Race�������� name�������������Ժ����ǿ���ͨ���������������������ҳ���

�һ�������ҵIJ��ҳ������һ����������ָ�����κ������в������� all�IJ��ҳ�����ͼ�ҵ� һ��ʵ���������а������� all�IJ��ҳ����� findAllByName���ܹ�����һ��ʵ�� Collection�� List���嵥 5 չʾ�� findByName���ҳ���

�嵥5. һ������ Entity ���������ļ򵥲��ҳ���

  1. static def findByName(name){
  2. def query = new Query(Race.class.simpleName)
  3. query.addFilter("name", Query.FilterOperator.EQUAL, name)
  4. def preparedQuery = this.datastore.prepare(query)
  5. if(preparedQuery.countEntities() > 1){
  6. return new Race(preparedQuery.asList(withLimit(1))[0])
  7. }else{
  8. return new Race(preparedQuery.asSingleEntity())
  9. }
  10. }

����򵥵IJ��ҳ���ʹ�� Google App Engine �� Query�� PreparedQuery����������һ������Ϊ “Race” ��ʵ�壬�����ƣ���ȫ����ͬ�ڴ�������ơ�����г���һ�� Race���������׼�����ҳ��򽫷���һ���б��ĵ�һ����Ƿ�ҳ���� 1��withLimit(1)����ָ���ġ�

��Ӧ�� findAllByName�������������ƣ���������һ��������ָ�� ����Ҫ��ʵ����������嵥 6 ��ʾ��

�嵥 6. ͨ�������ҵ�ȫ��ʵ��

  1. static def findAllByName(name, pagination=10){
  2. def query = new Query(Race.class.getSimpleName())
  3. query.addFilter("name", Query.FilterOperator.EQUAL, name)
  4. def preparedQuery = this.datastore.prepare(query)
  5. def entities = preparedQuery.asList(withLimit(pagination as int))
  6. return entities.collect { new Race(it as Entity) }
  7. }

��ǰ�涨��IJ��ҳ������ƣ�findAllByNameͨ�������ҵ� Raceʵ�������������� ���� Race��˳��˵һ�£�Groovy �� collect�����dz���������ɾ������ Raceʵ���Ķ�Ӧ��ѭ����ע�⣬Groovy ��֧�ַ���������Ĭ��ֵ�������������û�д���� 2 ��ֵ��pagination��ӵ��ֵ 10��

�嵥7. ���ҳ����ʵ������

  1. def nrace = Race.findByName("Charlottesville Marathon")
  2. assert nrace.distance == 26.2
  3. def races = Race.findAllByName("Charlottesville Marathon")
  4. assert races.class == ArrayList.class

�嵥 7�еIJ��ҳ����ռȶ��ķ�ʽ���У�findByName����һ��ʵ������ findAllByName����һ�� Collection���ٶ��ж�� “Charlottesville Marathon”����

“������” ����û��̫�಻ͬ

���������ܹ��������ҵ� Race��ʵ�������ڿ��Դ���һ�����ٵ� Runner�����ˡ���������봴����ʼ�� Raceʵ��һ���򵥣�ֻ�����嵥 8 ��ʾ��չ Model��

�嵥 8. ����һ�������ߺܼ�

  1. package com.b50.nosql
  2. class Runner extends Model{
  3. public Runner(params){
  4. super(params)
  5. }
  6. }

���� �嵥 8���Ҹо��Լ�������ɹ����ˡ����ǣ��һ��贴�������ߺͱ���֮������ӡ���Ȼ���ҽ�������ģΪһ�� “��Զ�” ��ϵ����Ϊ��ϣ���ҵIJ����߿��ԲμӶ��������

û�мܹ�����ģ

Google App Engine �� Bigtable ����ij�����һ���������ij��󣻼����Ҳ���ԭ���洢��ϵ�������Թ���������ˣ�Ϊ��ģ��� Race�Ͷ�� Runner֮��Ĺ�ϵ���ҽ���ÿ�� Raceʵ���д洢һ�� Runner��������ÿ�� Runnerʵ���д洢һ�� Race����

�ұ�����ҵļ�������������һ���߼������ǣ���Ϊ��ϣ�����ɵ� API �Ƚ���Ȼ —�Ҳ���ѯ��һ�� Race�Ի�ȡһ�� Runner�����������Ҫһ�� Runner�����˵��ǣ��Ⲣ����ʵ�֡�

���嵥 9 �У����Ѿ����������������� Raceʵ������һ�� Runnerʵ�������ݵ� addRunner����ʱ�����Ķ�Ӧ id�����ӵ��ײ� entity�� runners������פ���� id�� Collection�������һ���ֳɵ� runners�� collection�����µ� Runnerʵ���������ӵ��������򣬽�����һ���µ� Collection������� Runner�ļ���ʵ���ϵ� id���ԣ������ӵ�����

�嵥9. ���Ӳ�����������

  1. def addRunner(runner){
  2. if(this.@entity.runners){
  3. this.@entity.runners << runner.id
  4. }else{
  5. this.@entity.runners = [runner.id]
  6. }
  7. }
  8. def getRunners(){
  9. return this.@entity.runners.collect {
  10. new Runner( this.getEntity(Runner.class.simpleName, it) )
  11. }
  12. }

���嵥 9 �е� getRunners��������ʱ��һ�� Runnerʵ�����Ͻ��ӵײ�� id���ϴ�����������һ���·�����getEntity������ Model���д��������嵥 10 ��ʾ��

�嵥10. ��һ��id ����һ��ʵ��

  1. def getEntity(entityType, id){
  2. def key = KeyFactory.createKey(entityType, id)
  3. return this.@datastore.get(key)
  4. }

getEntity����ʹ�� Google �� KeyFactory���������ײ�������������ڲ������ݴ洢�е�һ������ʵ�塣

��󣬶���һ���µĹ��캯��������һ��ʵ�����ͣ����嵥 11 ��ʾ��

�嵥11. һ�������ӵĹ��캯��

  1. public Model(Entity entity){
  2. this.@entity = entity
  3. }

���嵥 9��10�� 11���Լ� ͼ 1�Ķ���ģ����ʾ���ҿ��Խ�һ�� Runner���ӵ���һ Race��Ҳ���Դ���һRace��ȡһ�� Runnerʵ�������嵥 12 �У����������ʽ�� Runner���ϴ�����һ�����Ƶ���ϵ���嵥 12 չʾ�� Runner����·�����

�嵥12. �����߼������

  1. def addRace(race){
  2. if(this.@entity.races){
  3. this.@entity.races << race.id
  4. }else{
  5. this.@entity.races = [race.id]
  6. }
  7. }
  8. def getRaces(){
  9. return this.@entity.races.collect {
  10. new Race( this.getEntity(Race.class.simpleName, it) )
  11. }
  12. }

�������Ҿ�ʹ��һ����ģʽ���ݴ洢���������������

ͨ��һЩ����������������

��ǰ���������Ǵ���һ�� Runnerʵ�����������ӵ�һ�� Race�������ϣ�������ϵ��˫��ģ���ͼ1���ҵĶ���ģ����ʾ����ô��Ҳ��������һЩ Raceʵ����һЩRunner�����嵥 13 ��ʾ��

�嵥 13. �μӶ�������Ķ��������

  1. def runner = new Runner([fname:"Chris", lname:"Smith", date:34])
  2. runner.save()
  3. race.addRunner(runner)
  4. race.save()
  5. runner.addRace(race)
  6. runner.save()

��һ���µ� Runner���ӵ� race�����Ӷ�Race��save�ĵ��ú�������ݴ洢��ʹ��һ��ID ���£���ͼ 3 �е���Ļ������ʾ��

ͼ3. �鿴һ������еĶ�������ߵ�������

ͨ����ϸ���Google App Engine �е����ݣ����Կ�����һ��Raceʵ������ӵ����һ��Runners ��list����ͼ 4 ��ʾ��

ͼ4. �鿴�µIJ������б�

ͬ�����ڽ�һ�� Race���ӵ�һ���´����� Runnerʵ��֮ǰ��������Բ������ڣ���ͼ 5 ��ʾ��

ͼ5. һ��û�б����IJ�����

���ǣ���һ�� Race������һ�� Runner�����ݴ洢�������µ� races ids �� list��

ͼ6. һ���μӱ����IJ�����

��ģʽ���ݴ洢�����������ˢ�� —���԰�����Ҫ�Զ����ӵ��ײ�洢����Ϊ������Ա����������»���ļܹ�����̸���ϲ���ܹ��ˣ�

NoSQL ������

��Ȼ����ģʽ���ݽ�ģҲ�����бס��ع�����ı���Ӧ�ó�������һ�������Ƿdz�������� ������һ�������ԣ����� SSN�����ӵ�һ�� Runner���Ҳ��ؽ��д������ —��ʵ�ϣ�����ҽ������԰����ڹ��캯���IJ����У���ô���ͻ��Զ����ӡ�����Щû��ʹ��һ�� SSN �����ľ�ʵ�����ԣ�������ʲô���飿ʲôҲû����������ӵ��һ��ֵΪ null���ֶΡ�

��һ���棬���Ѿ���ȷ����Ҫ����һ���Ժ�����������ȡЧ�ʡ����Ӧ�ó���ĵ�ǰ���ݼܹ�û�� ����ʩ���κ����� —�������ҿ���Ϊͬһ�����󴴽����޸�ʵ������ Google App Engine ����ļ����������£����Ƕ���Ωһ�ļ������������Զ���һ�µġ��������ǣ�����ɾ�������ڣ���������ʹ����ͬ�ļ�������ģһ�� “һ�Զ�” ��ϵ��ɾ�����ڵ㣬��ô�ҵõ�һЩ��Ч���ӽڵ㡣��Ȼ���ҿ���ʵ���Լ��������Լ�� —���ؼ��ǣ��ұ������Զ��֣����������������һ������

ʹ����ģʽ���ݴ洢��Ҫ�����ļ��ɡ�����Ҵ����������͵� Races —��Щ�����ƣ���Щû�У���Щ�� date���ԣ�����һЩ�� race_date���� —��ô��ֻ���ڰ���ʯͷ���Լ�����ʹ���ҵĴ�����ˣ��Ľš�

��Ȼ��Ҳ�п�������ʹ�� JDO��JPA �� Google App Engine���ڶ����Ŀ��ʹ�ù���ϵģ�ͺ���ģʽģ�ͺ��ҿ���˵ Gaelyk �ĵͼ� API ����ʹ����㡣ʹ�� Gaelyk ����һ���ô����ܹ������˽� Bigtable ��һ�����ģʽ���ݴ洢��

������

����ʱ��������ȥ����ʱ�����������ǣ����ǵĽ�������һ���³����������з��ļһ���� NoSQL ��������̫��һ��ʱ�У������Ǹ߶ȿ������� Web Ӧ�ó��򿪷���һ�����˻�����NoSQL ���ݿⲻ����� RDBMS�����ǣ����ǽ��������������ɹ��Ĺ��ߺͿ�ܻ��ڹ�ϵ���ݿ⣬RDBMSs �����ƺ�û�����ٹ�ʱ��Σ�ա�

��֮��NoSQL ���ݿ�������������——��ϵ����ģ���ṩһ����ʱ���������������������չʾ����Щ�����ǿ��еģ����Ҷ���һЩ�ض��ġ��߶�ǿ�Ƶ������������á���ģʽ ���ݿ�����������Ҫ�������ݼ����Ϳ������ԵĶ�ڵ� Web Ӧ�ó������ǻ���һ�����õĸ����ã�������������Ա��һ����������ӽǡ������ǹ�ϵ�ӽǽ������ݽ�ģ��

���������뵽��http://bbs.cnitom.com

����Ķ�

ͼ���ȵ�

��Щ��ҵ������Ҫϵͳ�߱�������չ����
��Щ��ҵ������Ҫϵͳ�߱�������չ�����ڴ�֮ǰ�������û�п��ǹ����IT������Ҫһ��������չ(Ҳ��������չ)ϵͳ������...
DB2 10�¹��ܣ���OracleǨ�Ƹ�����
DB2 10�¹��ܣ���OracleǨ�Ƹ������������һЩ�� �ֲ����� �˹�������PL/SQL��SQL PL����BEGINEND���ж���ֲ�����...

�����ȵ�