2/28/2016

어떤식으로 시스템을 만들어야 할까?

제품 개발에는 비용, 품질, 기간, 범위라는 네가지 제약 조건이 있다. 기간을 무시하고 빨리 개발하려고 밀어붙이면 품질이 저하되거나 개발 인력이 늘어나 폭발적인 비용을 감수해야 한다. 물론, 기간만 단축시키고 개발 인력을 늘리지 않는 곳도 존재한다.

같은 비용으로 더 나은 품질의 소프트웨어를 만들려면 기능을 축소하거나, 소수 정예의 개발자들이 충분한 시간을 가지고 개발을 하는 것이 현실적이다. (맨먼스 미신도 있지 않은가?) 비즈니스의 성격에 따라 위 변수중 어떤것을 우선해야 할지 결정해야 한다. 좋은 시스템을 만든다는 것은 위 변수의 값이 타당해야 한다. 비즈니스/시장상황에 의해 위의 방정식이 무의미한 극단적인 프로젝트도 존재하겠지만 그러한 방정식의 해답은 없다. 이런 경우 실현 불가능한 것을 가려내고, 추후 실현 가능한 대안을 제시해야 되지만 비기술자가 결정을 내리는 경우에는 엉망인 코드만 양산할 뿐이다. 이 세상에는 기술로 이해할 수 없는 것들이 많이 존재한다.

유쾌한 브레인스토밍의 7가지 비밀



브레인스토밍은 연습이 필요하다. 연습을 통해 잘할 수 있는 방법을 찾게되고 결국 잘하게 된다.
문제를 명확하게 묘사하여, 참여하는 사람들이 쉽게 주제에 접근 할 수 있도록 해라. 가령 “개인 정보 유출에 대한 보상”은 브레인스토밍 주제로는 좋지 않다. “개인 정보를 유출당한 사람들의 화를 삭힐 수 있도록 도와주는 방법” 처럼 적극적으로 참여할 수 있는 구체적 주제를 제시해야 한다.
아이디어를 비판하거나 반박하면서 시작하지 마라. 이런 부분은 “활기 약화”로 이어질 수 있다.
가장 중요한 것은 아이디어의 질이지만 브레인스토밍 진행전에 참가자를 자극하는 도구가 된다.
“방을 떠나기 전에 백 가지 아이디어를 냅시다.”
관념적인 얘기들로 아이디어가 정체될 때 활력을 불러일으켜야 한다. 마치 국민MC처럼 팀의 에너지가 고갈될 무렵 능력을 발휘해야 한다.
아이디어를 기록하는 방법은 여러가지가 있겠지만, 모임이 시작되기 전에 모든 벽에 낙서가 가능한 종이를 붙여라. 아이디어를 벽의 여백에 쓰면서 이리저리 방안을 걸어다니면 시너지 효과가 생겨난다.
다음과 같은 상황에서는 워밍업이 필요하다. 함께 일한 적이 없는 모임인 경우 브레인스토밍 초보자들로 구성된 경우 주의가 산만해졌을 때
만져보고, 느껴보고, 살펴본다.
-유쾌한 이노베이션 中

2/12/2016

MongoDB Schema Design — Part #1

이제까지 MongoDB를 로그 분석용으로 주로 활용했었고 다른 용도로 사용 할 경우에 스키마를 어떻게 구성해야 하는지에 대해서 검색한 결과를 정리한다. RDBMS의 스키마 디자인과는 다른 전략으로 접근해야 하고 아래 사항을 고려해야 한다.
  • User requirement 기반으로 스키마를 디자인한다.
  • 데이터를 read할 때 join하는 것이 아니라 데이타를 write할때 join해야 한다.
  • 객체간의 관계를 고려한다. (Multiple collection과 Embedded)
MongoDB는 아래의 방법으로 관계를 표현 할 수 있다.
> db.person.findOne() { name: ‘Kate Monster’, ssn: ‘123–456–7890’, addresses : [ { street: ‘123 Sesame St’, city: ‘Anytown’, cc: ‘USA’ }, { street: ‘123 Avenue Q’, city: ‘New York’, cc: ‘USA’ } ] }
위와 같이 embedded 방법을 쓸 경우에는 한 Query로 모든 정보를 가져 올 수 있다는 장점이 있지만, embedded details 정보만 독자적으로 가져 올 수 없다는 단점도 존재한다.
Embedded된 데이터의 크기가 증가하게 될 경우에 document의 사이즈 제한을 넘어서는 일이 생길 수 있다. 아래와 같이 part의 document가 있다고 하면,
> db.parts.findOne() { _id : ObjectID(‘AAAA’), partno : ‘123-aff-456’, name : ‘#4 grommet’, qty: 94, cost: 0.94, price: 3.99 }
각각의 Product는 하나의 document를 가지고 part document의 ObjectID를 array로 가지고 있는 구조로 구성한다.
> db.products.findOne() { name : ‘left-handed smoke shifter’, manufacturer : ‘Acme Corp’, catalog_number: 1234, parts : [ // array of references to Part documents ObjectID(‘AAAA’), // reference to the #4 grommet above ObjectID(‘F17C’), // reference to a different Part ObjectID(‘D2AA’), // etc ]
위와 같은 경우에는 application-level join으로 두 document를 연결하여 사용해야 한다.
// Fetch the Product document identified by this catalog number > product = db.products.findOne({catalog_number: 1234}); // Fetch all the Parts that are linked to this Product > product_parts = db.parts.find({_id: { $in : product.parts } } ).toArray() ;
각 document를 독자적으로 관리 할 수 있다는 장점이 있지만 각 document를 여러 번 호출해야 한다는 단점이 존재한다.
event logging system처럼 많은 양의 데이터를 처리해야 할 경우에는 16MB document size의 제한 때문에 위에서 언급한 방법을 사용하지 못한다. 이런 유형에서는 parent-referencing 방식을 사용해야 한다.
> db.hosts.findOne() { _id : ObjectID(‘AAAB’), name : ‘goofy.example.com’, ipaddr : ‘127.66.66.66’ } >db.logmsg.findOne() { time : ISODate(“2014–03–28T09:42:41.382Z”), message : ‘cpu is on fire!’, host: ObjectID(‘AAAB’) // Reference to the Host document }
application-level join을 사용하여 데이터를 가져온다.
// find the parent ‘host’ document > host = db.hosts.findOne({ipaddr : ‘127.66.66.66’}); // assumes unique index // find the most recent 5000 log message documents linked to that host > last_5k_msg = db.logmsg.find({host: host._id}).sort({time : -1}).limit(5000).toArray()
References: