[TIL - 1021] Spock가 뭐길래, 인덱스(1), int(11)이 뭘까?
test
spock 사용해보기
- 기존에 자바 코드(+spring)를 테스트할 때는 JUnit(unit test), Mockito(integration test)을 사용해서 테스트를 했는데, 워크샵에서 groovy로 테스트 코드를 작성하는 것을 보고 무엇인지 보았더니 Spock 였음
/* build.gradle Spock 추가 : mvnrepo(Core Module) : 스프링 환경에서 테스트 하는 것이 아니므로 Core만 */
dependencies {
testCompile group: 'org.spockframework', name: 'spock-core', version: '1.1-groovy-2.4'
}
- junit과 비교했을 때 Spock는 어떤 특징을 가지는지 알아보았음
- POJO 테스트
/* 테스트 대상 코드 */
public class Person {
private static NameRule rule = BasicRule.of();
private String name;
public Person(String name) {
if (!rule.isValid(name)) {
throw new RuntimeException("올바르지않은 이름 설정");
}
this.name = name;
}
}
/* Spock : 디펜던시 추가 후 테스트 클래스 생성할 때 테스트 프레임워크 선택할 수 있음 */
def "기본 룰 - 3자 미만"() {
given:
def invalidName = "te"
when:
new Person(invalidName)
then
def exception = thrown(RuntimeException.class)
exception.message == "블라블라"
}
/* 여러가지 한꺼번에 테스트하기 */
def "기본룰 테스트"() {
expect:
new Person(name)
where:
name | _
"jinbro" | _
"te" | _
"power" | _
"qw" | _
}
#######
Condition failed with Exception:
new Person(invalidName)
| |
| te
java.lang.RuntimeException: 올바르지않은 이름 설정
Condition failed with Exception:
new Person(invalidName)
| |
| qw
java.lang.RuntimeException: 올바르지않은 이름 설정
- 사용해보니
- 조금 더 테스트하도록 유도하는 점(블록 없이는 실행안됨 - 로그만 찍어보기가 아니라 결과 관련 블록 있어야)이 있음
- where 블록을 통해서 여러 케이스를 하나의 메소드로 묶어 테스트 할 수 있음 : 테스트 코드가 줄어듦 - JUnit의 경우 첫번쨰 실패 케이스만 알 수 있음
- Mock 테스트도 가능함 : Mock() 함수를 통해서
MySQL
인덱스(1) - 레코드를 저장하는 방식
- 검색 속도를 올리기 위한 레코드 저장 방식 : 검색(Select)속도를 올리는 대신 Insert, Update, Delete 속도는 느려짐
- 인덱스를 재편집 해야하기 때문에 : B+Tree 구조로 정렬해둔 상태
- 자주 사용되는 컬럼에 대해 인덱스를 걸어둠 : 검색 속도를 높여야할 필요성이 있는 데이터의 경우 불가피하게 선택할 수 밖에 없음
인덱스 종류
- Clustered Index : PK를 인덱스(자동 생성), PK를 기준으로 실제 데이터 위치까지도 변경됨, PK를 기준으로 검색하여 빠른 속도로 검색
- 인덱스의 Key가 PK
- 레코드의 위치를 Value로 가지고 있음 : PK로 검색하면 빠르게 데이터 위치를 찾을 수 있음
- BTree 구조
mysql> show index from employee\G;
*************************** 1. row ***************************
Table: employee
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 2
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
1 row in set (0.00 sec)
ERROR:
No query specified
- Secondary Index(Non Clustered Index) : 해당 인덱스를 만들 때에는 데이터 정렬 자체도 변경되지않고(실제 데이터 위치 변경없음), 해당 컬럼 기준 B+Tree만 하나 더 만드는 것
- PK를 Value로 가지고 있음 : PK를 찾아 Clustered Index로 다시 가서 레코드 위치를 찾음
- BTree 구조
- 풀스캔해서 찾는 것보다 트리구조로 되어있는 상태에서 검색하는 것이 더 빠름
- FK는 자동으로 인덱스 생성
mysql > create index idx_employee_createdtime on employee (created_time);
- Cardinality(인덱스 선정 기준 중 하나) : 사전의 뜻으로는 농도, 카디널리티가 높다는 뜻은 걸러낼 수 있는 데이터가 많다는 것
- sex(성별 컬럼)를 인덱스로 잡을 경우 남/여 50%만 걸러낼 수 있으므로 성능상 이점을 가져갈 수 없음
- 반대로 단순하게 auto_increment 설정된 int 타입의 Primary Key에 대한 인덱스가 자동생성되었는데, 각각 다 다르고 걸러내기가 쉬움(카디널리티가 높음)
- index는 내일 데이터 bulk insert 해두고 테스트를 해봐야겠음
궁금했던 것 - int(11)에서 (11)은 무엇을 의미할까?
- 디스플레이 옵션인데, 디스플레이할 때 비는 자리만큼 0을 채우도록(zerofill) 하는 옵션
- 디스플레이 적용하기위해서는 컬럼 지정 시 zerofill로 선언해야함
- int(11)을 사용하는 이유는? int가 4byte인데 unsigned 표현할 수 있는 데이터 범위가 21억… 10자리가 max size + 1
mysql > create table user ( id int(11) unsigned zerofill not null auto_increment, name varchar(16) not null, primary key (id) );
.
.
.
select * from user;
+-------------+------+
| id | name |
+-------------+------+
| 00000000001 | a |
| 00000000002 | b |
| 00000000003 | c |
| 00000000004 | d |
| 00000000005 | e |
+-------------+------+