레이블이 mysql인 게시물을 표시합니다. 모든 게시물 표시
레이블이 mysql인 게시물을 표시합니다. 모든 게시물 표시

2018년 9월 27일 목요일

mysql 계층형 메뉴 정렬 하는 쿼리


계층형 메뉴 정렬 하는 쿼리

CREATE DATABASE test default CHARACTER SET UTF8;

use test;

DROP table IF EXISTS menu;
CREATE TABLE menu (
  no int PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50) NOT NULL,
  parent int NULL,
  depth int NOT NULL,
  sequence int,
  reg_date DATETIME,
  modify_date DATETIME
)ENGINE=INNODB;
DESCRIBE  menu;

DROP TABLE menu;

INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date) VALUES("메뉴1" ,0 ,1, 1, now(), now());
INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴1-1" ,1 ,2, 1, now(), now());
INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴1-2" ,1 ,2, 2, now(), now());
INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴1-1-1" ,2 ,3, 1, now(), now());

INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴2" ,0 ,1, 2, now(), now());
INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴2-1" ,5 ,2, 1, now(), now());
INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴2-2" ,5 ,2, 2, now(), now());
INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴2-1-1" ,6 ,3, 1, now(), now());

INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴1-1-2" ,2 ,3, 2, now(), now());
INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴2-1-2" ,6 ,3, 2, now(), now());
INSERT INTO menu(name, parent, depth , sequence, reg_date, modify_date)  VALUES("메뉴2-1-3" ,6 ,3, 3, now(), now());
SELECT * FROM menu;

/* 계층형 mysql 쿼리 정렬 함수 */
DROP FUNCTION IF EXISTS hierarchy_connect_by_parent_eq_prior_no;
DELIMITER $$
CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_no(value INT) RETURNS INTEGER
NOT DETERMINISTIC
READS SQL DATA
  BEGIN
    DECLARE _parent INT;
    DECLARE _rank INT;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;

    SET _parent = @id;
    SET _rank = 0;

    IF @id IS NULL THEN
      RETURN NULL;
    END IF;

    LOOP
      SET @innerrank = 0;
      SELECT p.no
          INTO   @id
      FROM   (
             SELECT   no, @innerrank := @innerrank+1 AS ran
             FROM     menu
             WHERE    COALESCE(parent, 0) = _parent
             ORDER BY sequence
             ) p
      WHERE   p.ran > _rank LIMIT 0, 1;
      IF @id IS NOT NULL OR _parent = @start_with THEN
        SET @level = @level + 1;
        RETURN @id;
      END IF;
      SET @level := @level - 1;
      SET @innerrank = 0;
      SELECT COALESCE(p.parent, 0), p.ran
          INTO   _parent, _rank
      FROM   (
             SELECT no, parent, @innerrank := @innerrank+1 AS ran
             FROM    menu
             WHERE   COALESCE(parent, 0) = (
                                           SELECT COALESCE(parent, 0) FROM menu WHERE no = _parent
                                           )
             ORDER BY sequence
             ) p
      WHERE p.no = _parent;
    END LOOP;
  END;
$$
DELIMITER ;

/* 계층형 메뉴 정렬*/
SELECT  CONCAT(REPEAT('    ', depth  - 1), CAST(ou.no AS CHAR)) AS no, parent, depth, CONCAT(REPEAT('    ', depth  - 1), CAST(ou.name AS CHAR)) AS name, sequence, level FROM (
                 SELECT mn.name , mn.no, depth , parent, sequence, level FROM (
                                                               SELECT hierarchy_connect_by_parent_eq_prior_no(no) AS no,
                                                                      @level AS level
                                                               FROM (
                                                                    SELECT @start_with := 0, @id := @start_with, @level := 0
                                                                    ) vars, menu
                                                               WHERE @id IS NOT NULL
                                                               ) m
                                                                 JOIN menu mn ON mn.no = m.no
                 ) ou;

/* 계층형 mysql 쿼리 정렬 함수 - 특정 번호 */
DROP FUNCTION IF EXISTS hierarchy_connect_by_parent_eq_prior_id;
DELIMITER $$
CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INTEGER
NOT DETERMINISTIC
READS SQL DATA
  BEGIN
    DECLARE _no INT;
    DECLARE _parent INT;
    DECLARE _next INT;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET @no = NULL;

    SET _parent = @no;
    SET _no = -1;

    IF @no IS NULL THEN
      RETURN NULL;
    END IF;

    LOOP
      SELECT  MIN(no)
          INTO    @no
      FROM    menu
      WHERE   parent = _parent
        AND no > _no;
      IF @no IS NOT NULL OR _parent = @start_with THEN
        SET @depth = @depth + 1;
        RETURN @no;
      END IF;
      SET @depth := @depth - 1;
      SELECT  no, parent
          INTO    _no, _parent
      FROM    menu
      WHERE   no = _parent;
    END LOOP;
  END;
$$
DELIMITER ;

/* 조건에 따라 메뉴 출력 */
SELECT mn.name , mn.no, depth , parent, sequence
FROM    (
        SELECT no, @depth  AS vars_depth FROM menu WHERE no= '원하는메뉴번호'
        UNION ALL
        SELECT  hierarchy_connect_by_parent_eq_prior_id(no) AS no, @depth  AS vars_depth
        FROM    (
                SELECT  @start_with := '원하는메뉴번호',
                        @no := @start_with,
                        @depth  := 0
                ) vars, menu
        WHERE   @no IS NOT NULL
        ) fn
          JOIN    menu mn
            ON      mn.no = fn.no;
참고사이트
Share:

2017년 12월 9일 토요일

mysqldump를 이용한 데이터 이관시 속도 개선 방법

1. mysql 에서 아래 옵션을 변경

myisam_sort_buffer_size = 1000M
myisam_max_sort_file_size = 12G
스토레지 엔진을 myisam으로 변경한 다음 insert 완료후

alter database **** engine=innodb

2. innodb_flush_log_at_trx_commit 설정 값 변경

innodb_flush_log_at_trx_commit 값이 1인경우 insert 할때 로그파일을 기록한다. 이로인해 초당 몇천건 정도 insert할 내용을 몇십건 정도 insert한다.

show variables like 'innodb_flush_log_at_trx_commit';
DB dump파일을 import 할때는 로그가 요 없으므로 0 으로 설정하고 변경 값 확인후 insert한 다음 추후 설정값을 다시 복구한다.

set global innodb_flush_log_at_trx_commit=0;

3. table 별로 백업 sql 만들기

db_root_pw='비밀번호'

db_list=`echo "show databases;" | mysql -N -uroot -p"$db_root_pw"`
 for db in $db_list ;do
  table_list=`echo "show tables" | mysql -N -uroot -p"$db_root_pw" $db`
  for table in $table_list ; do
    mysqldump -uroot -p"$db_root_pw" $db $table > $db.${table}.sql
  done
 done

4. 옵션을 통해 시간 줄이기

--no-autocommit=1 : autocommit을 끄고 개의 테이블 입력 완료후 commit 수행, 오류 발생시 다시 처음부터 시작함

--single-transaction=1 : 작업 후에 변경 된 데이터의 내역을 다시 적용하지 않는다.

--extended-insert=1 :  INSERT 구문이 늘어나는 것을 막아준다.

- export 할때

mysqldump -hHOST_NAME -uMY_ID -pMY_PASSWORD --databases DB_NAME --tables TABLES_OF_DB_NAME --no-autocommit=1 --single-transaction=1 --extended-insert=1 > DUMP.sql
- import 할때

mysql -hHOST_NAME -uMY_ID -pMY_PASSWORD --database DB_NAME < DUMP.sql 

5. txt 파일이용하기

- export 할때
mysqldump DATABASE_NAME > DUMP.txt
- import 할때

mysql -u username -p –database=DATABASE_NAME < DUMP.txt

6. large dump

mysql -h localhost -uroot -pPASSWORD
set global net_buffer_length=1000000;
set global max_allowed_packet=1000000000;
SET foreign_key_checks = 0;
SET UNIQUE_CHECKS = 0;
SET AUTOCOMMIT = 0;
source /media/dbdump.sql
완료후
SET foreign_key_checks = 1;
SET UNIQUE_CHECKS = 1;
SET AUTOCOMMIT = 1;

7. 기타

my.cnf 위치찾기
mysql --verbose --help | grep -A 1 'Default options'
/etc/my.cnf 파일에서
innodb_buffer_pool_size = 4G
innodb_log_buffer_size = 256M
innodb_log_file_size = 1G
innodb_write_io_threads = 16
innodb_flush_log_at_trx_commit = 0
설정 후 와 데이터 입력후 2번 실행
service mysql restart 

키워드 : mysql big data fast import

*reference

Share:

2017년 7월 18일 화요일

Linux에서 FTP 업로드 mysql 설치

1. MySQL 다운로드 

https://dev.mysql.com/downloads/mysql/

2. 다운받은 파일 /usr/local/src에 FTP 업로드

3. 압축 해제

tar zxvf ./mysql-5.1.73.tar.gz

4. mysql 계정생성

groupadd mysql
useradd -g mysql -s /bin/bash -d /home/mysql mysql

5. 컴파일 및 make, make install

5.1 컴파일 설정
cd /usr/local/src/mysql-5.1.73
./configure --prefix=/usr/local/mysql --with-charset=utf8 --with-extra-charsets=all --with-mysqld-user=mysql --with-innodb --localstatedir=/usr/local/mysql/data
※ 컴파일 옵션 설명
--prefix=/usr/local/mysql : install 위치
--with-charset=utf8 : 기본 캐릭터셋
--with-extra-charsets=all
--with-mysqld-user=mysql : 유저명
--localstatedir=/usr/local/mysql/data : 데이터베이스의 데이터를 저장할 디렉토리를 설정

5.2 컴파일이 오류없이 정상적으로 되었다면 make, make install 입력
make
make install

6. DB설정


/usr/local/mysql/bin/mysql_install_db --user=mysql
vi /etc/profile
6.1 insert 버튼 누른후 제일 하단에 내용 추가후 esc 누르고 wq(저장하고종료) 입력

export PATH=$PATH:/usr/local/mysql/bin
6.2 mysql 환경설정 기본 파일 복사

cp /usr/local/mysql/share/mysql/my-medium.cnf /etc/my.cnf
mkdir -p /usr/local/mysql/data //data폴더 없을시 생성
mysql:mysql /usr/local/mysql/data

7. 서버 부팅시 mysql 자동실행

cp /usr/local/mysql/share/mysql/mysql.server /etc/rc.d/init.d/
cp /usr/local/mysql/share/mysql/mysql.server /etc/rc.d/init.d/mysql
chkconfig --level 3 mysql on
chkconfig --level 5 mysql on
chmod 755 /usr/local/mysql

8. DB 시작

service mysql start //시작
service mysql stop  //종료

9. mysql root 패스워드 변경

mysql -p mysql
//Enter password: 엔터
update user set password=password('패스워드') where user='root';
flush privileges;
quit

10. 3306번 보트 방화벽 권한 설정

iptables -I INPUT 1 -p tcp --dport 3306 -j ACCEPT
service iptables save //방화벽 규칙을 저장
vi /etc/sysconfig/iptables //상단에 추가되었는지 확인
service iptables restart //재시작

11. 접근권한이 없을시 ( Host 'HOST이름' is not allowed to connect to this MySQL server )

mysql -p mysql
GRANT ALL PRIVILEGES ON *.* TO root@'아이피' IDENTIFIED BY '비밀번호' WITH GRANT OPTION;
flush privileges; 
quit
Share:

linux에서 mysql 파일 실행하고 접근하는 방법

1. FTP업로드후 경로로 이동후 sql 파일 실행


cd /usr/local/mysql/bin

./mysql -u root -p mysql > ./파일명.sql

2. Table 'mysql.tableName' doesn't exist error 시 mysql 접속후 데이터베이스 변경

./mysql -u root -p mysql 접속

use DB명

source 파일명.sql

3. 작업환경에서 ERROR : com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:Table 'DATABASENAME.TableName' doesn't exist


//모든 원격지에서 접속 권한 추가
grant all privileges on DB명.* to 유저아이디@'%' identified by '비밀번호';
flush privileges;

//권한확인
SHOW GRANTS FOR root@'%'

4. TABLE 대문자로 쿼리사용시 EROOR날때

vi /etc/my.cnf
[mysqld] 아래에 lower_case_table_names=1을 insert 버튼눌러서 추가 하고 esc 누르고 !wq로 저장
[mysqld] lower_case_table_names = 1

//mysql재시작
sudo service mysql restart
Share:

2017년 5월 11일 목요일

mysql 특정 db 권한 주기

1. mysql  접속

2. 사용자 확인

use mysql;
select user, host from user;

3. db 만들기

create database DB명;

4. user 생성

user 생성
insert into user(host,user,password,ssl_cipher,x509_issuer,x509_subject)
 values ('localhost','사용자명',password('비밀번호'),'','','');
외부접근은 host 를 % 로 변경

변경사항 적용
flush privileges;

5. 특정 db 권한주기

grant all privileges on DB명.* to 사용자명@호스트 identified by '비밀번호';

6. 권한 확인

SHOW GRANTS FOR 사용자명;


Share:

2016년 8월 2일 화요일

phpmyadmin 에서 excel import 하는법

★ 데이터 작성법
1. 양식 excel 에 데이터를 넣는다.
( 해당 DB내보내기 에서 excel 다운받는다. )
2. 다른이름으로 저장을 선택해 csv 로 선택한다.
3. 다른이름으로 저장한 파일을 메모장으로 열어서 첫줄은 지우고 다른이름으로 저장 선택후 저장 버튼 왼쪽에 있는 인코딩을 UTF-8로 저장후 저장한다.


★데이터 넣는법
1. 브라우저 켠후 주소 pypmyadmin 주소 입력
2. 로그인 접속후
3. 해당 DB에서 상단 Import 클릭
4. 파일선택후 파일 첨부 ( csv로 저장한 파일 )
5. 하단 CSV using LOAD DATA 선택
6. 필드 구분자 , 입력  //  열(칼럼) 이름에
메모장에서 삭제한 첫줄 입력
7. 실행 버튼 클릭






Share:

2016년 4월 8일 금요일

mysql 같은 테이블 값 불러와서 넣는법

*insert

( SELECT * FROM ( SELECT 컬럼 FROM 테이블 WHERE ID= #{id} ) as temp )


*update

update table set column=1 where column2 IN (select column from table)
이렇게 하면 오류나지만 아래 처럼하면 사용가능

update table set column=1 where column2 IN (select * from (select column from table) as temp)

Share: