Kivy.org python 으로 만드는 cross platform application

멀티 터치. 빠르게 개발, 빠르게 running.

iOS 는 향후 출시.

Open Source..

GPU acceleration  .. Open GL

 

 

Advertisements

몽고 디비 MongoDB The Definitive Guide.. Ch. 3

Ch. 3  Creating, Updating, and Deleting Documents

Add, Remove, Update, level of safety vs. speed

Inserting and Saving Documents

Batch Insert

Single TCP request.  한꺼번에 보내면 헤더 중복이 안됨. 배치..
배치는 어플에서 사용하도록 의도. 많은 센서 데이터. 단, 하나의 컬렉션에 여러 다큐를 넣을 때에만 가능.
로 데이터 처리는 mongoimport 를 사용.
16 MB 한계.

Inserts : Internals and Implications

Insert :: BSON 으로 변환. 디비는 이 형식을 이해하고 _아이디 체크. 4 MB 를 넘지 않으면 데이터 validation 을 수행 안하고 바로 그대로 저장.
부작용 : 불량한 데이터 삽입 가능. injection attack 에 안전 ??
모든 메이저 언어의 드라이버는 유효성 검사를 수행.
확실하지 않은 드라이버를 돌릴 때는 디비 서버를 –objcheck 옵션으로 시작할 수 있음.

4메가 이상은 저장 불능. 임의의 한계. 불량 스키마 예방, 퍼포먼스를 위한 것임. 사이즈를 보려면 Object.bsonsize(doc) 을 쉘에서 입력.
전쟁과 평화가 3.14 메가임.

디비는 삽입 시 별로 하는 일이 없으므로 인젝션 어택에 약하지 않음.  고전적인 인젝션 어택은 몽고디비에서는 불가능. 대안 적인 어택.

Removing Documents

db.users.remove()  >> user 컬렉션 전체 삭제. 컬렉션은 살림. 인덱스 삭제. 쿼리를 통해 조건 부여 삭제.

db.mailing.list.remove( { “opt” : true } )  # mailing.list 컬렉션의 opt 값이 참 인 ㅅ람 모두 삭제.

삭제는 undo 없음.

Remove Speed

1만개 삭제 : 맥북에어에서 46초..  드랍을 하면 0.01 초..
전체 컬렉션과 인덱스 삭제..

Updating Documents

2 parameters : query document, modifier document

Document Replacement

Atomic.  Last update will “win” ..  “survive ” ..
같은 조건의 데이터가 여러개 일 때 주의..   update 가 분명한 다큐를 가리켜야함.  “_id” 처럼..

Using Modifiers

데이터 일부만 변경 시..  altering, adding, removing keys, manipulating arrays, embedded documents, _id 는 변경불가.

db.analytics.update({“url” : “www.example.com”},
… {“$inc” : {“pageviews” : 1}})   # 페이지 뷰 늘리기.

[1] Getting started with the “$set” modifier

키에 상응하는 밸류 세팅. 키가 없으면 생성.  밸류의 타입도 변경 (스트링 -> 어레이)
임베디드 다큐의 속성 변경 가능. { “$set” : { “author.name” : “some name” } }  …
$unset :: remove the key.

[2] Incrementing

$inc modifier. :: 현재의 키 증가시킴, 없으면 키 생성. 변경 가능 숫자일 때 유용.  analytics, votes ..  게임 점수 증가.  int, long, double 에 가능.

[3] Array modifiers

$push : 추가..  동일한 내용을 추가하지 않으려면 $ne 쿼리를 병행행
$addToSet : 역시 동일한 내용은 추가 안함.  $each 와 함께 여러개 삽입 가능. ($ne / $push 사용 불가)
<어레이 요소 삭제 방법>
[1] $pop :: 큐 / 스택 처럼 사용하고 싶으면 $pop 사용. { $pop : { key : 1 } } 는 어레이의 끝 요소 삭제. { key : -1} 은 처음 멤버 삭제.
[2] $pull ::  조건으로 검색. 삭제.  매칭되는 여러개 모두 삭제.

[4] Positional array modifier

어레이의 여러 값 변경 방법.  포지션 또는 포지션 연산자 $ 사용.
{ “$inc” : { “comments.0.votes” : 1 } }   # 포지션 지정.. 0번째.  하지만, 많은 경우 위치를 모름. 이때 $ 사용.

db.blog.update( {“comments.author” : “John” },
… { “$set” : { “comments.$.author” : “Jim” } })  # 여러 커멘트에서 작성자 이름을 변경.  (첫번째 것만)
## 첫번째 매치 만 업데이트 함…

[5] Modifier speed

각 명령어마다 성능차이 존재. $inc 는 키에 해당하는 값만 변경하므로 매우 빠름. 대신 어레이 변경자는 다큐의 크기를 변경하므로 느려짐.
($set 역시 비슷함.)
몽고는 사이즈 변경에 따른 완충장치를 두었지만, 원래보다 훨씬 크게 고치면 새로 지정함. 어레이 크기 조정, 어레이 수정 등은 속도 저하.
예제 파이썬 프로그램.   10배 차이..
$push 가 버틀넥인 경우 임베디드 어레이를 별도의 컬렉션에 두는 것도 한 방법.

Upserts [p36]

문서를 찾아서 업데이트하거나, 없으면 생성. 쿼리와 인서트 를 하는 일반적인 경우는 ‘레이스’ 조건 직면.

The ‘save’ Shell Helper

업서트와 비슷. 다큐 인자를 하나 받음. _id 키가 있으면 업서트 실행, 없으면 인서트 실행.
쉘에서 신속하게 수정할 수 있는 방법.

Updateing Multiple Documents [p38]

Update 는 첫번째 요소만 수정. 4번째 인자에 true 를 세팅함으로 모든 멤버 수정 가능. (나중에 바뀔 소지가 있음..  그러므로, 항상 값을 넣을 것. 참/거짓)
멀티 업데이트는 스키마 변경시에 당연히 유리.  생일 선물 주기 기능 ..
몇개가 수정되었나 ? getLastError database command.  ==>  “n” : 5

Returning Updated  Documents [p39]

< getLastError > 로 부터는 제한된 정보밖에 없다. 그래서 findAndModify 가 필요.
일반적인 업데이트와는 약간 다르게 불리고, 느림. 디비 응답을 기다려야 하기 때문.
큐를 조작하고 겟-셑 등의 미세 조작을 수행할 때 편하다.

예> READY, RUNNING DONE 의 세 상태를 갖고 있으면.
“레디”를 가져와서
이놈을 “러닝” 으로 바꾸고.. 액션을 시작한 후 끝나면
“던” 으로 바꾸는 과정을 해야 함.
이 과정은 “레이스 조건”. 대안은 복잡.
타이밍에 있어서도, 한 프로세스는 계속 놀고 있을 수 있음.  이럴 때 적합..
< findAndModify > 는 아이템을 리턴하고 업데이트를 한 조작내에서 가능.
리턴된 놈은 업데이트 전이지만, 컬렉션에서 찾아보면 업데이트가 되어있슴.
<삭제 : “remove” : true … >도 가능..

Key of findAndModify
findAndModify
query
sort
update
remove
new

매칭 다큐가 없으면 에러.
한 개의 다큐만 가능.
<업서트> 로 사용 불가.  기존의 다큐만 수정 가능.
속도 : find, update, getLastError 를 연속 실행할 때 만큼 느림.

The Fastest Write This Side of Mississippi [p41]

삽입, 제거, 업데이트는 보내고 잊어버리는 타입. 빠르다. fire-and-forgot
로그 기록 등에서는 무방하나 결재 시스템에서는 허용할 수 없음.

Safe Operations

관계형 디비 위의 어플리케이션중 많은 부분이 리턴 코드를 확인 안함. 몽고는 디폴트로 체크하지 않음.
Safe version 은 getLastError 명령어를 실행함. 드라이버는 디비 반응을 기다리고 적당한 에러를 핸들하고 예외를 던짐.
성공하면 그에 따르는 정보를 포함함.

Catching “Normal” Errors

Safe operation 은 ‘이상한’ 디비 행동을 디버그 하는 방법이기도 함.  개발중에는 널리 사용해야 함. 여러 에러를 방지할 수 있음.  가장 흔하게는 중복 키 에러.
중복키의 경우 삽입 실패를 모르고 넘어갈 수 있음.

Requests and Connections

몽고디비 서버의 각 연결마다 디비는 연결의 요청에 따른 큐를 생성한다. 클라이언트가 연결에 요청하면 큐의 끝에 놓여지고, 다음의 요청은 큐에 있는 작업이 실행된 후에 실행된다. 그러므로, 단일 커넥션은 디비의 consistent view 를 갖고 자신의 쓰기를 읽을 수 있다.
이것은 per-connection queue. 쉘을 두개 열면 이것은 2개의 연결임. 한쪽에서 넣은 후에 다른쪽에서 읽으면 리턴 못받음. 하지만, 한 쉘에서는 삽입 후 쿼리는 리턴 함.  수작업으로는 재현 힘들지만 바쁜 서버에서는 가능한 얘기.
한 쓰레드에서 작업하고 다른 쓰레드에서 확인하는 것은 무의미.   특히, 루비, 파이썬, 자바 드라이버에서.   => connection pooling 사용.

Unix for OS X Mountain Lion Ch. 1 ~ 3

>> PIP install **  ; python install related..

>> PATH 추가… / etc / paths 파일에 추가 .. 리부팅.. sudo vi paths … ^ ^

>> ps -acx ; process status ps -ax | grep  **  ; 검색. kill 1234 .. >> cp *-ab-* *kb ~ ; copy *** files to home folder..

>> 모든 명령어 : sht + esc -> ?

>> 10가지 명령어. ls, -a (show all) -l (full info) cp  originalFile copiedFile mv originalFile newFile rm fileName pwd :: present working directory cd directoryName man commandName :: manual 읽기 less fileName :: display long text file. grep pattern filename(s) top

>> Cmd + .   or Ctrl – C  ..  취소, 지우기 : Del  / Ctrl + H,  새로운 줄 시작 : Ctrl + U > 프로그램 종료하고 쉘로 복귀 : Ctrl + D

>> tab :: 자동 완성.. 폴더/파일 이름.   두번 치면 리스트 나옴..

>> du -s :: 현 폴더 크기 계산.. recursively..

>> chsh : change shell..   korn shell is more advanced features in shell programming..

>> 멈췄을 때 조치 :: return key, cmd – . , ctrl – Z, Ctrl- C / Q, ctrl – D (new line)

Ch. 3 File System

OS X Filesystem

유닉스에서는 모든 것은 파일.. 폴더도 파일…

Home Directory

echo $HOME

Your Working Directory ( = current directory, pwd  : present working directory )

The Directory Tree

ls /  :: show hidden folder

Files in the Directory Tree

파일이 아닌것도 파일처럼. symbolic link , socket
$ touch someName :: 새 파일 생성.

Listing Files and Directories

Trying > ls < command

# ls -1 :: line one column
# ls -F ::    folderName/ … / 표시…  * 실행파일.. @ 심볼릭 링크 표시시
# ls -s :: Size… (512 byte of >> BLOCKSIZE << )
# ls -d Library :: 폴더가 있는지만 확인.. 리스트는 안하고..

Using the l option  (long format)

drwxrwxr-x 10 unity staff 340 1 31 17:40 Ubuntu One
-rw-r–r–@ 1 unity staff 85929 1 28 13:40 get-pip.py

Total n ::  total size in BLOCK..  1024 bytes in OS X..
d (directory or ) – (file)
Access Mode ??

ls -F ::  directory에 / 추가해서 보여줌.
ls -R  :: Recursive..

Calculating File Size and Disk Space

du :: disk usage
du -s Library :: summarize ..
du -sh   :: G, M B 등의 단위로 표기.
du -s * .[^.]*  hidden file 포함 리스트..

Calculating Available Disk Space

dh -h  / -H / -m

inode : 작은 파일을 붙이는 기본 디스크 블럭.    -i

Protecting and Sharing Files

File Access Permissions

Setting Permissions with chmod

세팅 : owner (u), group (g), other (o), all (a)  ;; go : group and others.
Add (+), Delete (-), specify (=)
Read (r),  w, x ..

Example
chmod a-w filename   #  remove write permission of all
chmod u+w filename
chmod ug=rw * # all file setting.
폴더는 실행 권한이 있어야 열 수 있음.
chmod go-rwx dirName # 폴더 보호 목적
chmod go= dirName  # 같은 작용.
chmod u=rwx, go=rx dirName

Problem check list

Super User.. not the owner..
문제가 폴더에 있을 수도. cp 로 테스트.

Changing the Group and Owner :: “” chgrp, chown “”

sudo chown newowner filename

Changing Your Password [71] passwd 변경 명령어

Superuser Privileges with sudo

sudo find / -name makewhatis -print

Exploring External Volumnes

ls /Volumes ;; iPod directory search 가능..

MongoDB & Python Niall O’Higgins Ch 1, 2

Ch. 1.  Getting Started

Introduction

2009년 릴리스.  다이나믹한 디비.. 그런 파이썬과 잘 어울림.

Finding Reference Documentation

Installing MongoDB

Running MongoDB

맥 : 터미널에서 mongo 실행. 어드민 콘솔 실행.

Setting up a Python Environment with MongoDB

PyMongo driver package. 파이썬에서는 ‘가상 환경’ 을 만드는 게 연습에 좋다.  > virtualenv..
> 1. via manually >> python -c import setuptools
> 2. via system package management tool
유닉스 계열은 .. sudo port install py27-virtualenv   이런 식.

다음으로 PyMongo 드라이버 설치.

pip 설치..

< MY TIP >mongod : 서버, mongos : 클라이언트 사이드, mongo : 관리자 쉘..
http://docs.mongodb.org/manual/tutorial/manage-mongodb-processes/
mongod –dbpath /srv/mongodb/

Ch. 2.  Reading and Writing to MongoDB with Python

Connecting to MongoDB with Python

Getting a Database Handle

Inserting a document into a Collection

Collection 은 lazily 생성.  오타나면 그 이름으로 생성하므로 디버깅 어려움.
Primary key 자동 생성.  _id ..  96 bit .. identical value.. ObjectID object.. not incremental ID in RDBMS

Write to a Collection Safely and Synchronously

비동기 쓰기는 위험하므로 ‘항상’ ‘언제나’ 블락 writing 하라.

Guaranteeing Writes to Multiple Database Nodes

Node :: a single instance of MongoDB daemon process.   Normally .. a node a machine..
Replica Set :: master – slave replication..
만약을 위해 복제디비에 쓴다.. w=2 이러식

dbh.users.insert (user_doc, w=2)

Introducing to MongoDB Query Language

암시적 And.. Or 사용하려면 $or ..  greater than, less than .. 등 조건문.

q = {
“firstname” : “Jane”
“lastname” : “Doe”  # And … 자동으로…
“score” : { “$gt” : 25 }  # greater than 25 …
}

Reading, Counting, and Sorting Documents in a Collection

하나만 찾을 때 find_one()
크기만 알고 싶을 때 : 서버 쪽에서 count()  Cursor object..
Sort() ..  결과가 많고 그 중 일부만 가져올 때.. 게임 탑 순위를 걸를 때…  Limit()   .. performance benefit.. limit 0 = NO limit ^ *
Cursot.skip ()  page ..

users = dbh.users.find(snapshot = True).sort((“score”, pymongo.DESCENDING) ).limit(10)

Snapshot Mode.. 분석 도구.. 중복 방지.

Updating Documents in a Collection

값을 지정하고 전체를 업데이트 해야 함.. 딮 카피 후..
레이싱 문제 발생 가능.  그래서.. “update modifiers” 채용.
=> atomic increment / decrement, atomic list push / pop …   $set  를 사용하여 미리 쿼리를 안 해도 되게 함.

dbh.users.update( { “username” : “janedoe” },  { “$set” : { “email” : “janedoe74@examcle.com” } }, safe=True)

조건에 여러개가 맞아도 첫번째 하나에만 적용.   “multi = True” 파라메터 필요.

Deleting Documents from a Collection

dbh.users.remove( { “score” : 1 }, safe=True )

dbh.users.remove(None, safe=True) # delete ALL Documents in user collection …

drop_collection() 은 인덱스를 놔둔다.

MongoDB Query Operation

$gt, $lt, $in ….

MongoDB Update Modifiers..

$inc : Atomic Increment   “$inc”:{“score”:1}
$set : Set Property Value   “$set”:{“username” : “niall” }

몽고 디비 MongoDB The Definitive Guide.. Ch. 1, 2

그동안 시간이 많았는데 블로깅 하는 걸 잊고 살았슴다. 서버 개발자 찾아 삼만리..  하다가 조금씩 공부해 보기로 작정.. 일단 언어는 파이썬.. 디비는 당근 MySQL 로 생각했었는데, 이것도 요즘 대세인 하둡, NoSQL 쪽으로 가기로.. ㅎㅎ 점점 게임과는 거리가 멀어지는 듯.. 그러다가 몽고, 카산드라 사이에서 잠깐 고민하다가… 몽고 디비에 관한 책을 와우에서 구해서.. 둘다 얇고.. 하나는 파이썬과도 통하고… 해서 당장 오늘 시작

1장. Introduction

Powerful, flexible, scalable data store.. ? 데이터 [베이스] 가 아니라 [스토어] 라고라고라?.. 맵리듀스 스타일의 압축 도 지원하고.. 다양한 특성을 갖고 있다.

A Rich data model

‘row’ 단위보다는 ‘document’ 단위로 저장하여 스키마를 변경해도 유연하게 처리 가능하다.. RDB 는 꽉 짜여진 것이고… 몽고는 좀 느슨하다는 것 같음. 하나의 레코드로 복잡한 구조를 표현 가능하다. 또한 ‘스키마-프리’. 변경할 스키마가 없으므로 대량 데이터 이동 등이 불필요. 새로운 / 사라진 키는 모든 디비를 똑같이 강제하기 보다는 어플리케이션 레벨에서 처리.  데이터 모델 진화에 유연하게 대처 가능.

Easy Scaling

데이터가 커지는데 대처하는 방법 : Scale Up (bigger machine), or  Scale Out (partitioning data across more machines) 몽고는 처음부터 스케일 아웃에 대비해 설계됨. Document-oriented data model 은 자동으로 여러 서버에 나눠 저장. 개발자는 로직에 집중할 수 있음. 저장공간이 더 필요할 때 단지 클러스터에 기계를 더 붙이고 나머지는 디비가 알아서 함.

Tons of features

Indexing :: generic secondary indexes.  geospatial indexing.. Stored JavaScript :: Instead of stored procedures, JS functions… Aggregation :: Map reduce. Fixed size collection :: capped collections .. such as logs.. File storage :: large files and meta data.

.. Without Sacrificing Speed

속도를 위한 … binary wire protocol   memory mapped files ..dynamic query optimizer

Simple Administration

설정이 적다.. ㅎㅎㅎ

2장. Getting Started.

> Document : 기본 데이터 단위.. row 에 해당.
> Collection : 테이블 ..
> 하나의 인스턴스가 여러 디비를 호스트 할 수 있음.
> 강력한 JavaScript Shell.
> _id : special key.

Documents

>   ordered set of keys with associated values  > 언어마다 다른 정의 ? 자바스크립트에서는 object

{“greeting” : “Hello, world!”, “foo” : 3 }
>> 순서가 있음.
>> 밸류는 특정 테이터 타입이 있음.
>> 키는 스트링.  은 제외.  키의 종료를 의미.   $와 . 역시 예약어.  _ 로 시작하는 것도 피할 것.
>> 타입, 케이스 센시티브 함..
>> 중복 키 금지.

Collection

Group of Documents.

Schema Free

컬렉션은 스키마-프리.
아무거나 들어갈 수 있는데, 왜 별도의 컬렉션이 필요한가?
> 종류별로 구별
> 타입을 리스트 하기보다, 컬렉션을 리스트하는게 더 빠름.
> 인덱스 ??

Naming

> “”, /0, system 으로 시작, $ 불가

Subcollection

[.] 으로 분리 (예: blog.posts) 이때 blog 와는 전혀 무관. 이름만 지음.
드라이버에서 유용한 방법 제공.
데이터를 구성하는 유기적 방법을 제공하므로 ‘강력 추천’

Databases

컬렉션으로 그루핑하고, 컬렉션들을 데이터베이스로 그루핑한다.  하나의 인스턴스는 여러 데이터베이스를 호스트 가능.  완전히 독립적으로.
데베는 독립된 퍼미션, 독립된 파일에 저장.
하나의 어플은 같은 데베에 저장을 추천. 여러 파일은 여러 어플이나 동일 몽고디비 서버의 여러 사용자일 때 .
데베는 이름으로 구별.

> “” 널문자 불가
> 소문자
> 64바이트

특별한 디비 네임.

> admin : root database.
> local :
> config :

mds 디비의 blog.posts 컬렉션이면 mds.blog.posts 네임스페이스를 얻게 됨.  네임스페이스는 121바이트 한계.

Getting and Starting MongoDB

서버로 실행됨.  => mongod  실행.
인자 없이 실행시키면 디폴트 데이터 폴더 이용. /data/db/  & port 27017. 없거나 쓰기불능이면 페일. 포트 페일도 페일. => 다른 인스턴스가 돌고 있을 때.
기본 http 서버 셋업. 28017.  관리를 http://localhost:28017 웹 브라우저로 가능.
종료 : Ctrl – C

MongoDB Shell

JS shell. 관리에 매우 편함.

Running the Shell

JavaScript interpreter 전체임.  멀티라인 가능. 문장이 끝났는지 검토.

MongoDB Client

또한  stand-alone MongoDB client 이다.  기동 시 셀은 몽고 디비의 test 디비에 연결하고 이것을 전역변수 db 에 할당함.  이 변수가 주된 접속 포인트임.
애드온. SQL shell과 유사함. 추가 함수는 없지만 나이스한 구문 제공.

> use foobar
switched to db foobar

자바 스크립트이므로 변수를 치면 변수를 스트링으로 바꿔 프린트한다.
컬렉션 역시 db 를 통해 접속 가능. db.baz 는 baz  컬렉션 리턴.

Basic Operations with the Shell

CRUD (create / read / update / delete)

Create

함수 insert 는 컬렉션에 다큐먼트 추가.

> post = { “title” : “My Blog Post” , “content” : “Here’s my post.”, “date” : new Date() }
> db.blog.insert(post)  .. 저장됨.
> db.blog.find()  확인.  “_id” : ObjectID (“asd2dbad33kj;adsfklj3kl;sd”)  이런게 추가됨.

Read

find() , findOne()  20개 다큐먼트 보여줌.

Update

두개의 인자. 어느 다큐먼트를 업데이트 할지 criteria, new document.

> post.comments = []
> db.blog.update( { title : “My Blog Post” } , post)  >> “comments” key 가 추가됨.

Delete

인수 없이 불려 모든 걸 지움.

> db.blog.remove( { title : “My Blog Post” } )  >> 요것만 지움.

Tips for Using the Shell

> help  >> built in help..
> db.help();  or   db.foo.help();

괄호 없이 함수명을 치면 뭘하는 지 알 수 있다.

> db.foo.update

Inconvenient collection names

디비 클래스의 속성만 아니면 컬렉션을 가져올 수 있다. db.version 은 디비 함수이므로 안된다. ??   getCollection 사용.
> db.getCollection(“version”);
예를 들어 foo-bar 는 유효한 컬렉션 이름이지만, 자바스크립트에서 variable subtraction 이다.
> db.getCollection(“foo-bar”)

JavaScript x.y = x[‘y’] 임.

Data Types

Basic Data Types

JSON 식. 자바스크립트와 비슷.   JSON : null, bool, numeric, string, array, object 6가지 종류.. 제한적임.  언어에 따라 다르지만 몇가지 추가함.

Numbers

몽고 디비는 4 / 8 비트 정수, 8비트 실수가 있으므로 자바스크립트를 약간 우회?해야 함.
디폴트 : 몽고에서는 모든 숫자는 더블 로 간주.   디비에서 4정수를 꺼내 가공한 후 저장하면 더블로 저장됨.
또다른 문제는 8정수가 더블로 표현되지 않음.   “floatApprox” 와  “top” “bottom” 키워드로 표현..

Dates

항상 new Date() 하라.. 객체 리턴.. 그냥 하면 스트링만 리턴.   자바스크립트 방식..  디비에는 기준 시점 이후의 밀리세컨드로 저장.

Arrays

어레이 내에 다른 타입을 가질 수 있음.  어레이를 멤버로 가질 수도 있음.
몽고는 이 구조를 이해함.  어레이에 대한 쿼리 가능..
원자적 업데이트 가능.. (하나를 바꾸는 액션)

Embedded Documents

Value 값으로 할당된 다큐먼트..   주소 : { 나라 : 콩고, 시 : 시티, 구 : 용산 } 이런식으로 표현 가능.. RDB 에서는 다른 테이블 필요하지만 몽고는 불필요
더 자연스럽게 정보를 표현.
단점 >> 정보가 반복될 수 있다.

_id and ObjectIds

어느 타입이든 가능.  각 컬렉션에는 고유한 아이디 필요.. 다른 컬렉션은 동일 아이디 가능.

ObjectIds

12 bytes. 24 hexadecimal digits.
> 4 byte : Time Stamp .. 입력 순서대로 정렬 가능..  암시적 타임 스탬프.
> 3 byte : Machine .. hash of the machine’s hostname.
> 2 byte : Process ID
> 3 byte : Incremental.  256 ^ 3 = 16,777,216 … in a single second..

Autogeneration of _id