반응형
반응형

최근 로그성 데이터를 수집하여, RDB에 넣어놓고

내림차순하여 일정량의 데이터를 보여주어야 하는 API를 만들일이 생겼다.


그냥 날쿼리나 mybatis를 사용하면 간단하겠지만, 귀찮으므로 spring jpa를 이용해서 해결해보기로 하였다.


요구사항은 두가지


1. 데이터량 제한 (limit or top)

2. 내림차순 (order by asc | desc)


저 두 가지 요구사항 모두 Spring JPA의 JpaRepository를 구현한 인터페이스에 메소드 명 정책만 맞춰주면 해결이 된다.


// 시퀀스 기준으로 내림차순한 결과를 300개만 가져오는 메소드명

public List<?> findTop300ByOrderBySeqDesc();

구글링을 해보면, 보통 findTop300 다음에 조건문을 넣기 위해 컬럼명을 넣게 되는데,

필요없는 경우에는 컬럼명을 생략이 가능하다. (이런 예제가 없어서 하루종일 헤맴;;)


Order By는 그냥 쿼리 작성하듯이 자연스럽게 작성해주면 된다.


역시 jpa는 편리하군

반응형

'개발 > JPA, Hibernate' 카테고리의 다른 글

[Hibernate] Hibernate Validator  (0) 2016.06.11
[Hibernate] Custom Validator  (0) 2016.06.11
[Hibernate] ddl-auto  (0) 2016.06.11
[Hibernate] Entity 선언 시 주의점  (0) 2016.06.11
[Spring Data Jpa] custom query 적용  (0) 2016.06.11
,
반응형

JpaRepository를 상속받은 후, @Query라는 Annotation을 이용해서 custom query를 작성 가능한데,

이 Annotation의 property중 nativeQuery라는 게 있다.


커스터마이징한 쿼리의 결과가 JpaRepository 상속 시 선언된 Object의 클래스형과 동일하거나 해당 Object에 포함된 컬럼이라면,

@Query에 커스텀 쿼리만 작성을 하면 되지만, 쿼리에서 컬럼에 alias를 걸어서 이리저리 지지고 볶는 경우에는 분명히 리턴 값이 달라지게 된다.


이런 경우에는 nativeQuery를 true로 잡아주지 않으면, 서버가 올라가면서 테이블이 매핑되지 않았다고 뭐라뭐라한다.


여기까지하면 서버 올라갈때 문제는 없는데, 직접 쿼리 실행할 때 주의할 점이 있는데..

@Query에 value로 쿼리를 넣을 때 쿼리가 길면 정리하고 싶어지게 마련인데.. 띄어쓰기 같은거 다 체크하는거 같음.. 왠만하면 보기싫어도 그냥 쭉 길게 쓰는걸 추천.. (hsqldb에서만 그런걸지도;;)


전반적으로 jpa가 편하긴 한데, 국내에 사용하는 사람이 별로 없어서인지 몰라도 예외상황이 발생하면, 자료 찾기가 너무 힘들다; 

반응형

'개발 > JPA, Hibernate' 카테고리의 다른 글

[Hibernate] Hibernate Validator  (0) 2016.06.11
[Hibernate] Custom Validator  (0) 2016.06.11
[Hibernate] ddl-auto  (0) 2016.06.11
[Hibernate] Entity 선언 시 주의점  (0) 2016.06.11
[Spring Data Jpa] limit와 ordering  (1) 2016.06.11
,
반응형

A DB를 사용하고 있는데 전혀 다른 곳에 있는 B DB에 있는 테이블을 참조하고 싶을 때 사용한다.

CREATE [PUBLIC] SYNONYM A.SYNONYM명 FOR B.테이블명;

 

이렇게 SYNONYM을 생성하고 나면 위에서 명시한 B DB의 테이블에 있는 데이터를

A.SYNONYM명을 통해 가져올 수 있다.

A.SYNONYM은 일반 테이블처럼 사용할 수 있다.

SELECT *
FROM A.SYNONYM명

위의 쿼리를 날리면

SELECT *
FROM B.테이블명

B테이블의 데이터를 가져올 수 있다는 의미이다.

 


반응형
,
반응형

저희 사내 DB중에 mysql을 sharding 시켜서 이용하는 DB가 있습니다. 

 

하지만, 단점이 join을 사용하였을 경우, 쿼리 속도가 안드로메다가 된다는 점인데요.

 

다른 부서로 가신 분께 인수인계를 받은 소스 중에 DB가 sharding되어 있다는 점을 전혀 고려하지 않고,

개발이 되어 있던 쿼리가 있어서, 초반에 고객들이 별로 없었을 때는 문제가 없었지만,

고객이 많아지니까 쿼리 속도가 15초가 나오더군요-_-

 

그래서 일단 join을 제거하고, 소스 상에서 처리를 하였는데요.

여전히 느리더군요..

 

또 다시 문제를 파악하던 도중 문제를 발견했는데,

근본적인 문제는 특정 컬럼을 기준으로 order by 하는 데 index가 걸려있지 않아서 느리던 현상이었습니다.

 

따라서, DBA분께 요청해서 index를 생성하는 방향으로 해결하기로 했었습니다.

 

하지만, index를 생성하였는데도 속도가 그대로군요.

 

해당 쿼리가 어떤 index를 사용하고 있는지, explain명령어를 통해서 보았는데..

다른 index를 사용하고있더군요-_-..

 

그래서 강제로 방금 생성한 index를 사용하도록 쿼리를 수정하였더니 0.1초도 안걸렸습니다.

 

아래와 같이 사용하시면 됩니다.

SELECT *
FROM A use index {인덱스명}

반대로 인덱스를 사용하고 싶지 않은 경우

SELECT *
FROM A ignore index {인덱스명}
반응형
,
반응형

한 번 만들다가 실패한 이후에, 다시 만들려고하면

만들어지지도 않은 테이블이 이미 존재한다는 에러가 나온다. (아주 드물게...) 

 

이런 경우 ${MariaDBPath}/data/DB명 폴더에 가서, 테이블명.ibd파일을 지워버리고

다시 시도하면 만들어진다.

버그라고 한다.. 

 

프로시저도 비슷한 현상이 있던데..

그때 상황에서 급해서 그냥 DB명을 바꿔버려서, 해결을 못했던 적이 있다.

 

프로시저 같은 경우는 테이블처럼 파일도 따로 안남는 것 같던데...

 

이건 나중에 발생하면 찾아보는걸로.. 

반응형
,
반응형

테이블만 캐릭터셋이 바뀐다고 다 바뀌는건 아니었고,

컬럼에 대한 캐릭터셋을 바꾸니 정상으로 동작한다.

 

mysql은 컬럼별로 캐릭터셋 설정이 가능하다는걸 오늘 첨 알게 되었다--;; 

 

위에 있는 글 없었으면 하루종일 삽질할뻔;;; 

반응형
,
반응형

MariaDB 5.2 버전 이후부터 VirtualColumn이라는 것을 지원한다는 것을 알게 되었고,

Oracle에서도 11g 버전 이후로 지원을 한다.

 

VirtualColumn이 하는 역할은, 테이블 하나에 있는 값들로 연산을 해야 하는데,

좀 반복적인 연산이다 싶은 경우에 VirtualColumn을 하나 두고, 표현식으로 계산식을 넣어두면,

Table에 Row가 쌓일때, 해당 표현식으로 계산이 되면서 VirtualColumn에 값이 들어가게 된다.

 

예를 들면,

a, b, c 컬럼이 있고, d컬럼을 a + 1이 들어가게 하고 싶다. 라고 한다면

d컬럼의 표현식에 a + 1을 넣어주고, 가상 컬럼임을 인지할 수 있게, VIRTUAL type으로 만들어준다.

본인처럼 로직 연산의 개념으로 사용하려면, 메모리를 직접적으로 사용하지 않는 VIRTUAL Type이 성능상 이점이 많다고 한다.

(sqlYog에서는 VIRTUAL type을 지정할 수 있는 UI가 없기 때문에, 본인처럼 CLI가 생소한 사람들은 HeidiSQL(http://www.heidisql.com/)을 사용하면 된다.)

 

기존에 있던 테이블을 고쳐서, Virtual Column을 하나 집어넣으려고 하니

Lock Timeout이라고 뜨면서 트랜잭션을 다시 시작하랜다..

데이터도 별로 없는 테이블인데 이렇게 뜨는걸 보면... 버그인가보다.

InnoDB lock timeout값을 아무리 늘려봐도 동일했다.

 

Virtual Column을 테이블에 두려면, 처음 구조부터 그렇게 잡고 가야하나보다.

 

참고로, user가 생성한 function은 표현식에서 지원을 하지 않는다.

또한, 안정성을 보장하기 위해(이건 그냥 주관적인 생각..), Virtual Column은 Nullable하게 설정이 된다.

 

기존 테이블을 Copy한 뒤, 만들고, 기존꺼 지우고, 새로 만든 테이블을 원래 테이블 이름으로 교체하니깐 잘 만들어졌다!

뭐.. 라이브 서비스 도중에 Virtual Column을 갑자기 넣는건 좀 말도 안되는 거고, 로직으로 처리하겠지...

개발단계니까 가능한일.. ㅋㅋ

 

퍼즐 게임을 만들고 있는데, 데이터가 1,2,3:4,5,2:3,3,2 이렇게 순차적으로 들어가게 되는데,

마지막 스테이지가 몇인지를 매번 코드에서 Split하다보니 짜증나기도 하고, 비효율적인 것 같기도하고 해서..

Virtual Column으로 만들어버리고, Getter를 이용해서 손쉽게 사용하고 있다.

 

마지막 스테이지를 구하려면 :가 몇개인지 카운팅하고 +1을 더해주면 되는 구조라서,

아래와 같은 표현식을 사용해서 구성했다.

SELECT LENGTH(@String) - LENGTH(REPLACE(@String, ':', '')) + 1

http://stackoverflow.com/questions/11835155/mysql-split-comma-separated-string-into-temp-table


String의 총 길이를 구해서, Delimiter를 빈값으로 치환하고 치환된 문자열의 길이를 재서 원래 문자열의 길이와 Substract를 하면...

Replace를 통해 치환된 문자열의 총 길이를 알 수 있는 로직이다.

생각도 못했던 로직인데... 사용자 정의 function 미지원 소식을 듣고, 포기하기 직전에 StackOverFlow가 구원의 손길을 내려줌 ㅎㅎ

 

VirtualColumn이라는 새로운걸 알았으니, 자주 써먹어보도록 하자.


※ memcached등 캐시용도로 사용할때는, 메모리상에서 위의 함수를 구현해서

캐시에서 가져온 후, 함수 실행을 해주는 식으로 해야한다. (이거 때문에 큰일날뻔...)

반응형
,
반응형

SQL_Latin1_General_CP1_CI_AS 같은 경우 기본적으로 유니코드 대응이 되지만,

VARCHAR형태를 사용하면, 영어 및 특정 언어에 대해서만 대응이 가능하고, 한글이 깨져서 보이게 된다.


이럴 경우! NVARCHAR로 컬럼 타입을 바꿔버리면 해결이 된다.


여러가지 언어가 들어가는 컬럼의 경우 NVARCHAR를 사용해야 될 것 같다.


이렇게 바꿔도 안들어 갔었는데, 그건 쿼리가 잘못되서 였었다.


insert into T_TEST(A, B) values('가', '나')  --여전히 깨짐
insert into T_TEST(A, B) values(N'가', N'나')  -- 정상

NVARCHAR 컬럼에 수동으로 insert를 할 경우 앞에 꼭 N을 붙여야 한다.


MSSQL은 이번에 처음 다뤄보는거라.. 이글을 쓰면서 참 허접해보이는건 왜 일까 ㅠㅠ

반응형
,
반응형

SP 작성 중 INT 변수에 NULL을 기본값으로 넣고, 

!= 로 NULL이 아닌지 체크를 하여, 다른 쿼리를 실행할 일이 생겼었음.


근데 잘 안되길래, 뭔가 이상하다 싶어서 아래와 같이 테스트를 해봤는데..


DECLARE @i INT = NULL
SELECT @i

IF @i = NULL
    BEGIN
        SELECT 2
    END
ELSE 
    BEGIN
        SELECT 3
    END



NULL이라고 제대로 찍히면서, 밑에 IF문에서는 ELSE로 들어가는 것이었다.


여기저기 물어보니 표준 문법이 아니라서, 조건에 일치하지 않을거다라고 답변을 받고,

SET ANSI_NULLS OFF 이 옵션을 상단에 넣어주면 제대로 동작할거다라고 원인파악을 했다.


근데 SET ANSI_NULLS OFF 이 옵션을 쓰면!!

인덱스가 걸려있는 테이블에서 뭔가를 변경할 때 실패한다고 한다.


그래서 항상 SET ANSI_NULLS 는 ON으로 써야하고,

IF @i IS NOT NULL과 같이 표준에 맞게 사용하는것으로 정리가 되었음.


이럴꺼면, SP만들때 컴파일 에러나게 처리하는게 어려웠을까라는 생각이 든다.

ON을 표준으로 해놓고, 컴파일 에러나게 했었으면 개발자들 실수가 좀 줄어들었을텐데..

반응형
,
반응형

이미 다른 버전이 설치되어 있으면 확인 후 모두 삭제해야 한다.


$ rpm -qa | grep mysql

현재기준으로 CentOS 6.5버전에는 yum repository에 5.1버전밖에 없기 때문에,

5.5버전 설치를 위해서는 webtatic repo가 있는지 확인 후, 없으면 추가해주어야 한다.


$ rpm -qa | webtatic
$ rpm -Uvh http://mirror.webtatic.com/yum/el6/latest.rpm

설치한다.

$ yum --enablerepo=webtatic install mysql55w-server


서비스 실행

$ service mysqld start


※ repo 등록을 하지 않고 yum install mysql로 이미 설치를 해버린 경우,

yum remove mysql로 삭제가 제대로 되지 않는 경우가 있는데

이 경우 아래와 같이 rpm 명령어를 통해 삭제를 하면 된다.

$ rpm -e mysql
$ rpm -e --nodeps mysql-libs
반응형
,
반응형