mysql 테이블에서 컬럼을 삭제한다.


alter table `table_name` drop column `old_name`



mysql 테이블에서 컬럼을 변경한다.


alter table `table_name` change `old_name` `new_name` varchar(500) DEFAULT NULL;



mysql 테이블에서 컬럼을 추가한다.



alter table `table_name ` add column `new_name` int(11) default 0;



mysql 테이블에서 여러 컬럼을 추가한다.


alter table `stat_activities` add column actiontags_uv int(11) default 0, add column actiontags_pv int(11) default 0;





mysql과 달리 오라클에서는 테이블 변경을 다음처럼 진행한다.


ALTER TABLE `table_name` RENAME COLUMN `old_name` TO ;



'DB' 카테고리의 다른 글

mysql 완전 삭제  (0) 2017.09.27
mysql 5.7.5에서 크게 바뀐 내용  (0) 2017.09.27
ORDER BY RAND() / 범위 / 범위 미지정 쿼리  (0) 2017.04.13
[derby] validation query  (0) 2017.04.10
[mysql] auto increment 이슈  (0) 2016.12.19
Posted by '김용환'
,



대용량 DB 데이터에서 테스트해본 내용을 정리했다.



ORDER BY RAND()는 성능이 좋지 않아서 잘못하면 DB 성능에 악영향을 미칠 수 있다. 


SELECT name, birth FROM birthday ORDER BY RAND() LIMIT 10




index를 가진 필드를 기반으로 범위로 정하는 것이 조금 나은 형태인듯 하지만..


SELECT name, birth FROM birthday WHERE birth>=0101 and birth<=0131 LIMIT 10



그러나 대용량 데이터에서는 데이터가 많아지면서 범위 지정은 점차 성능 저하가 나타날 수 있다. 


따라서 범위를 정하지 않는 게 가장 낫다.



SELECT name, birth FROM birthday WHERE birth=0101 LIMIT 10


SELECT name, birth FROM birthday WHERE birth=0102 LIMIT 10



'DB' 카테고리의 다른 글

mysql 5.7.5에서 크게 바뀐 내용  (0) 2017.09.27
[mysql] 테이블의 컬럼 삭제, 변경, 추가  (0) 2017.06.18
[derby] validation query  (0) 2017.04.10
[mysql] auto increment 이슈  (0) 2016.12.19
[mysql] alter table after 필드  (0) 2016.11.16
Posted by '김용환'
,

[derby] validation query

DB 2017. 4. 10. 19:26



아파치 더비에서 validation query 를 사용하려 할 때 select 1은 에러를 발생한다.


아래 쿼리를 사용해야 validation query로 사용할 수 있다.


select 1 from SYSIBM.SYSDUMMY1


Posted by '김용환'
,

[mysql] auto increment 이슈

DB 2016. 12. 19. 20:09



mysql 의 auto increment 쪽은 약간 살펴봐야할 내용들이 있다.





auto increment 필드(예, id)를 가진 테이블에 insert into문을 사용할 때, auto increment 필드(예, i)가 순차적인 일련번호가 아닌 값이 나타나는 겨우가 발생했다. 



즉, insert into문을 사용할 때 일반적인 auto increment 필드는 1, 2, 3, 4, 5와 같은 순차적으로 늘어나는데, 1, 2, 3, 5 이렇게 나타날 수 있다. 



여러 원인이 있을 수 있다. 


1. insert ignore into 문을 사용하다가 statement문에 이슈가 발견되어 row가 insert되지 않아도 auto increment필드의 값이 증가될 수 있다.


2. insert into문이 포함된 transaction이 rollback 되는 경우 auto increment필드의 값이 증가될 수 있다.


3. concurrent한 insert into 문이 들어올 때 auto increment필드의 값이 증가될 수 있다.




따라서, auto increment 값을 신뢰해서 안되며 auto increment를 중요하게 쓸 것이라면, transaction에서는 사용하지 않는 것이 좋다. auto increment을 중요하게 쓸 계획이라면, innodb_autoinc_lock_mode을 알아야 한다. 

(mysql db에서 show variables 커맨드를 사용하면 확인할 수 있다)





mysql 5.0까지는 auto increment는 테이블 락이었지만, 5.1 부터는 테이블 락이 아닌 갭 락(gap lock)을 사용한다. 또한, mysql 5.0까지는 innodb_autoinc_lock_mode의 기본값이 0이었다가, mysql 5.1부터는 기본값이 1이 되었다. 




innodb_autoinc_lock_mode의 값 비교


0(tranditional)으로 설정하면, 테이블 단위의 락을 사용한다. 성능이 떨어진다. 

1(consecutive)로 설정하면, 단순한 insert into문에 락을 사용하지 않는다. bulk insert 문을 사용할 때 mutex(light weight lock)를 사용해 락을 사용한다.

2(interleaved)로 설정하면, 락을 사용하지 않는다. 빠르고 확장성이 좋지만, 복구가 어렵다. bulk insert 문을 사용할 때 엉망인 auto increment 값이 나타날 수 있다. 




innodb_autoinc_lock_mode의 값을 잘 보고 성능과 기능의 적당한 타협이 필요하다. 




참조 


http://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html#innodb-auto-increment-configurable


Posted by '김용환'
,

[mysql] alter table after 필드

DB 2016. 11. 16. 10:48

테이블에서 새로운 필드를 추가하려면 아래와 비슷한 타입으로 쓴다. 


alter table tableName add column columnName not null


이 때, 맨 마지막 컬럼에 위치하게 되므로 원하는 모델이 되지 않을 수 있다.


순서를 특정 컬럼 다음에 위치하려면, after를 사용한다. 



alter table tableName add column columnName not null after preColumnName


뿐만 아니라 first도 사용할 수 있다.





자세한 내용은 http://dev.mysql.com/doc/refman/5.7/en/alter-table.html를 참고한다.


To add a column at a specific position within a table row, use FIRST or AFTER col_name. The default is to add the column last. You can also use FIRST and AFTER in CHANGE or MODIFY operations to reorder columns within a table.


'DB' 카테고리의 다른 글

[derby] validation query  (0) 2017.04.10
[mysql] auto increment 이슈  (0) 2016.12.19
[mysql] SELECT .. INTO OUTFILE  (0) 2016.04.16
[mysql] INSERT INTO .. VALUES ON DUPLICATE KEY UPDATE.. 응답 값  (0) 2016.03.31
[MySQL] GROUP_CONCAT  (0) 2016.02.15
Posted by '김용환'
,

[mysql] SELECT .. INTO OUTFILE

DB 2016. 4. 16. 10:14



SELECT .. INTO OUTFILE을 사용하면 파일로 덤프할 수 있다. 



select id, name from members where id >= 1 INTO OUTFILE '/home/www/file.txt'




하지만, mysql master를 실행할 때, --secure-file-priv=path 옵션을 주어 실행했다면, slave에서도 SELECT .. INTO OUTFILE을 사용할 수 없다. 


즉, 아래와 같은 에러가 발생한다.



ERROR 1290 (HY000): The MariaDB server is running with the --secure-file-priv option so it cannot execute this statement



--secure-file-priv 변수를 확인해본다.


mysql> show variables like 'secure%';

+------------------+---------------+

| Variable_name    | Value         |

+------------------+---------------+

| secure_auth      | OFF           |

| secure_file_priv | /xxx/yyy |

+------------------+---------------+



mysql 슬레이브로 접근하여 secure_file_priv  옵션의 값에 맞게 SELECT .. INTO OUTFILE을 사용한다 하더라도, mysql client 의 로컬 디렉토리에는 전혀 저장할 수 없다.



select id, name from members where id >= 1 INTO OUTFILE '/xxx/yyy/file.txt'


실행은 되더라도 mysql master 서버에 위치한 /xxx/yyy에만 저장되니 원격에서 연결된 mysql client의 로컬 디렉토리에는 mysql 데이터를 저장할 수 없다. 






참고로,


secure_file_priv  옵션은 SELECT .. INTO .. 와 LOAD 문도 영향을 준다. 






'DB' 카테고리의 다른 글

[mysql] auto increment 이슈  (0) 2016.12.19
[mysql] alter table after 필드  (0) 2016.11.16
[mysql] INSERT INTO .. VALUES ON DUPLICATE KEY UPDATE.. 응답 값  (0) 2016.03.31
[MySQL] GROUP_CONCAT  (0) 2016.02.15
[mysql] SELECT CONVERT_TZ  (0) 2016.02.03
Posted by '김용환'
,



https://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html


With ON DUPLICATE KEY UPDATE, the affected-rows value per row is 1 if the row is inserted as a new row, and 2 if an existing row is updated.


mysql의 'INSERT INTO 테이블 VALUES ON DUPLICATE KEY UPDATE'에서 

데이터 추가되면 응답 값을 1로 리턴하고, 

업데이트되면 응답 값을 2로 리턴한다. 




Posted by '김용환'
,

[MySQL] GROUP_CONCAT

DB 2016. 2. 15. 18:35

Mysql의 GROUP_CONCAT() 함수가 있다. 이 함수의 예시는 다음과 같다.



CREATE TABLE `friend` (

`profile_id` int(11) DEFAULT NULL,

`friend_id` int(11) DEFAULT NULL

) ENGINE=InnoDB;


INSERT INTO friend(profile_id, friend_id) VALUES (1,1),(1,2),(1,3),(1,4),(2,1),(3,1),(3,2),(3,4),(4,1),(4,1)


SELECT DISTINCT profile_id, friend_id FROM friend ORDER BY profile_id



결과는 다음과 같다.




list 형태로 보려면 GROUP_CONCAT과 DISTINCT를 이용한다.


SELECT DISTINCT profile_id, GROUP_CONCAT(DISTINCT friend_id ORDER BY friend_id) friend_id_list 

FROM friend 

GROUP BY profile_id 

ORDER BY profile_id




, 가 아닌 ; 을 쓰려면 SEPARATOR를 이용한다.


SELECT DISTINCT profile_id, GROUP_CONCAT(DISTINCT friend_id ORDER BY friend_id SEPARATOR ';') friend_id_list 

FROM friend 

GROUP BY profile_id 

ORDER BY profile_id







GROUP_CONCAT 사용시 유의할 점은 디폴트 값이 좀 작다. 

다음 예시를 살펴보낟.



CREATE TABLE `friend2` (

`profile_id` int(11) DEFAULT NULL,

`friend_id` varchar(1000) 

) ENGINE=InnoDB;




INSERT INTO friend2(profile_id, friend_id) VALUES (1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111113')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111114')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111115')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111116')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111117')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111118')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111120')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111121')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111122')

,(1,'111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111123')



SELECT DISTINCT profile_id, GROUP_CONCAT(DISTINCT friend_id ORDER BY friend_id) friend_id_list 

FROM friend2

GROUP BY profile_id 

ORDER BY profile_id



결과를 보면, 맨 끝에 결과가 짤려 있다.


'1', '111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111110,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111112,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111113,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111114,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111115,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111116,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111117,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111118,111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111119,111111111111111111111111'




그 이유는 GROUP_CONCAT 의 디폴트 최대값은 1024이다. 따라서 1024가 넘어가면서 짤리는 현상이 발생한다.



> show variables like "group_concat_max_len";

+----------------------+-------+

| Variable_name        | Value |

+----------------------+-------+

| group_concat_max_len | 1024  |

+----------------------+-------+

1 row in set (0.00 sec)



이 문제를 해결하려면, group_concat_max_len 값을 길게 설정하거나 쓰지 않는다.


MariaDB [(none)]>  set @@group_concat_max_len = 50000;

Query OK, 0 rows affected (0.00 sec)


MariaDB [(none)]> show variables like "group_concat_max_len";

+----------------------+-------+

| Variable_name        | Value |

+----------------------+-------+

| group_concat_max_len | 50000 |

+----------------------+-------+

1 row in set (0.00 sec)




참고

http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html

http://ra2kstar.tistory.com/m/post/81

https://www.percona.com/blog/2013/10/22/the-power-of-mysqls-group_concat/



Posted by '김용환'
,

[mysql] SELECT CONVERT_TZ

DB 2016. 2. 3. 17:58





SELECT CONVERT_TZ('2016-02-02 00:00:00','+00:00','+09:00');


'2016-02-02 09:00:00'


주어진 시간 정보(첫 번째 인자)으로 from시간(두 번째 인자)을 to시간(세 번째 인자)로 바꿔주는 mysql 함수이다. 




참고

https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html

http://www.w3resource.com/mysql/date-and-time-functions/mysql-convert_tz-function.php






Posted by '김용환'
,


소수점 이하 2자리의 값을 Mysql에 저장할 때, 마지막 숫자가 0이면, 그 값은 mysql에서 지운다.

1010.10 이라는 값을 저장하면 1010.1 만 얻어올 수 있다.



언어를 통해서 Numberformat을 맞출 수 있지만, 간단히 mysql select 에서도 FORMAT을 이용해서 채울 수 있다. 


http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_format


예를 들어 SELECT  FORMAT(1010.1,  2) 의 결과는 1010.12 이다.


만약 as를 사용하고 있다면 다음처럼 쓸 수 있다. 


FORMAT(sum(avg_duration),2) as sumOfDuration

'DB' 카테고리의 다른 글

[MySQL] GROUP_CONCAT  (0) 2016.02.15
[mysql] SELECT CONVERT_TZ  (0) 2016.02.03
DB 별 default isolation level (play2의 db 설정의 isolation 레벨 관련)  (0) 2014.12.23
[Graph] Titan Graph DB  (0) 2014.09.04
[mysql] mysql 버전 가져오기 - shell  (0) 2014.08.25
Posted by '김용환'
,