Database 37

인덱스 설계에 필요한 선택도와 카디널리티

선택도(Selectivity)- 전체 대상 레코드 중에서 특정 조건에 의해 선택될 것으로 예상되는 레코드 비율을 말한다. 선택도 -> 카디널리티 -> 비용 -> 액세스 방식, 조인 순서,. 조인 방법 등 결정 1 1선택도 = --------------------- = -------------- Distinct Value 개수 num_distinct 카디널리티 (Cardinality)- 키다널리티(Cardinality)는 특정 액세스 단계를 거치고 나서 출력될 것으로 예상되는 결과 건수를 말하며, 아래와 같이 총 로우 수에 선택도를 곱해서 구한다. 카디널리티 = 총 로우 수 X 선택도 선택도, 카디널리티가 중요한 이유- 하나의 키값에 여러개의 row가 맵핑이 되는 경우에는 SELECT시 인덱스를 안타고 F..

Database/MySQL 2018.06.11

Group By 쿼리의 활용

Group By- 테이블에 저장되어 있는 데이터를 분리를 할때 사용되는 SQL Keyword- Having 절을 이용하여 Group By시에 조건을 줄수가 있다. 기본 SynatxSELECT column_name(s)FROM table_nameWHERE conditionGROUP BY column_name(s)ORDER BY column_name(s); Sample Query- Count를 이용하는 방법 : 하나의 key를 기준으로 가지고 있는 갯수가 2개 이상인 결과를 얻는 쿼리SELECT userId, count(userId) as cntFROM user_ordersGROUP BY userIdHAVING count(userId) > 1 - Count를 이용하는 방법 : user log를 이용하여 다른..

Database/MySQL 2018.06.09

@ EnableTransactionManagement Advice Mode PROXY와 ASPECTJ

낙관적 Lock (Optimistic Lock)을 이용해서 비즈니스 로직을 처리를 할때 클래스의 내부의 함수는 트랙잭션이 제대로 걸리지 않아 데이터가 저장이 되지 않았었다. 이와 관련해서 stackoverflow에 검색을 해보니 관련되서 질문을 올린 사람이 있었다. 관련해서는 실수를 하기 쉬운 것이라고 생각이 되서 블로그 글을 따로 정리를 한다.Option A@Transactional public void generate(){ // selects save(a); // more selects } @Transactional public void save(Object a){ //save the object }Option Bpublic void generate(){ // selects save(a); // mo..

Database/JPA 2018.06.03

Transactional with jpa repository

interface SampleRepository {} interfaces SampleJpaRepository implements JpaRepository, SampleRepository {} @Autowiredprivate SampleRepository sampleRepositry; - SampleRepositry라는 인터페이스를 두고 실제 SampleJpaRepository 구현체를 따로 두는 형식으로 구현을 할수가 있다.- 구조는 Domain Driven Design에서 인프라 설계부분 (여기에서는 JPA를 Infra라고 볼수 있다)을 인터페이스 두고 구현을 한 예제이다. 위의 코드는 비즈니스 로직을 작성을 할때 문제점이 발생이 될수가 있다.- 실제 Transaction은 SampleJpaRepost..

Database/JPA 2018.05.28

Database Transaction Lock With JPA

Database Transaction Lock With JPA데이터베이스의 Transaction Lock은 두가지 방식이 있다. 1. 낙관적 잠금- 다른 transaction이 수정이 할수가 있다.- version 컬럼을 두어 version 이 달라지는 경우 충돌을 알려준다.- JPA에서의 @Version 기능, 버전이 달라질 경우에는 OptimisticLockException 에러가 발생이 된다. @Lock Annotation- LockModeType.OPTIMISTIC- LockModeType.OPTIMISTIC_FORCE_INCREMENT - 업데이트가 되지 않는 경우에 강제로 version을 +1를 더한다. - 1:N의 구조의 데이터 인경우는 N에 해당하는 데이터를 추가할때 1에 해당하는 데이터가..

Database/JPA 2018.05.28

로그성 데이터의 날짜 기반의 index 설계

- 주로 Elastic Search를 사용하는 use-case가 로그 분석, 사용자 행동 분석 등을 사용한다.- 하지만 로그 분석 등의 데이터는 규모가 따라 다르지만 양이 생각보다 많다.- Document를 지우는것은 비용이 비싼 연산에 포함이 된다.- Document를 지우는 것보다는 Index를 삭제하는 것이 싼 연산이다.- 따라서 index 이름에 날짜를 포함시켜 시간이 지난 index는 삭제하는 방법이다 좋다.- index의 Type Mapping은 Template 기능을 이용하면 된다. ex)server_log-2018.01.01server_log-2018.01.02....

term aggregation 기능 사용하기

- SQL의 Group by의 기능을 필요하다면 Terms Aggregation을 사용하면 된다.- AVG, MAX 등의 데이터는 Metric Aggregation을 참고를 하면 된다- SQL의 distinct 기능으로 활용될수도 있다. - 참고자료 : https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html - Example SQL SampleSELECT genre, count(*) FROM docs GROUP BY genre - Term Aggregation QueryGET /_search{ "aggs" : { "genres" : { "terms" : { ..

_source를 이용하여 원하는 필드만 선택하기

- ElasticSearch Query를 사용하다보면 필요한 데이터만 가지고 오고 싶을때가 있다. 그럴 경우에는 "_source" 필드를 사용하여 데이터를 선택할수가 있다.- 하나의 데이터가 큰 경우에는 _source를 이용하여 네트워크 비용을 줄일수가 있다.- 참고 : https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-source-filtering.html - 필드를 선택을 하지 않는 경우 GET /_search{ "_source": false, "query" : { "term" : { "user" : "kimchy" } }} - nested 구조의 필드를 선택하는 경우GET /_search{ "_source":..

NoSQL DB의 1:N 데이터의 구조의 설계 방법의 종류

1:N 데이터의 구조의 설계 방법의 종류- Embedded Data Model- 1:N 구조의 데이터를 하나의 document로 표현하는 방법- 데이터의 용량이 커지는 경우에는 문제가 될수가 있다.- Normalized Data Model- 1:N의 구조를 데이터를 분리하여 저장을 하는 방법.- 기존 RDB에서 설계하는 방법과 동일하다.- nosql 에서는 join 기능이 제공을 하지 않기 때문에 application level에서 처리를 해줘야 한다. 설계 선택?- 데이터의 형태에 따라 구조를 다르게 설계를 하면 될듯.- Embedded Data Model를 가능 경우에는 하나의 Document가 비대해지것은 막기 위한 로직도 필요하다고 생각된다.

Database 2018.05.22

Elastic Search Nested Query

Nested Query- document에서 list의 object가 있는 구조- 일반적인 DB에서의 1:N 구조를 하나의 document에 포함시키는 구조로 갈수가 있다. Nested MappingPUT /my_index{ "mappings": { "type1" : { "properties" : { "obj1" : { "type" : "nested" } } } }}- Type : nested GET /_search{ "query": { "nested" : { "path" : "obj1", "score_mode" : "avg", "query" : { "bool" : { "must" : [ { "match" : {"obj1.name" : "blue"} }, { "range" : {"obj1.count" :..