'쿼리'에 해당되는 글 4건

  1. 2011.11.08 MySQL 쿼리를 활용해 지도 위치간 거리 계산하기
  2. 2011.09.20 모바일 어플리케이션의 성능 향상에 대해~
  3. 2011.09.03 MySQL 쿼리 결과를 파일로 저장하기
  4. 2007.06.08 MySQL 주요 명령어 모음

MySQL 쿼리를 활용해 지도 위치간 거리 계산하기

|



요즘 App을 개발하다보면 지도를 활용하는 어플이 많습니다. 
특히 현재 위치에서 다른 위치 사이의 거리를 계산해야 하는 경우가 있는데요..

Google API를 사용할 경우, distanceBetween과 같은 메소드를 활용할 수도 있을 겁니다.

오늘 정리할 내용은 MySQL 쿼리를 활용해서 두 위치 사이의 거리를 계산하는 겁니다.
오랜만에 보는 몇가지 수학함수를 사용하면 간단히 결과가 나오네요..

다음과 같이 가정하고 쿼리를 만들어 보도록 하겠습니다.

현재 위치
위도 : nowLat
경도 : nowLng

지정 위치
위도: setLat
경도: setLng

> select (6371 * acos( cos( radians(nowLat) ) * cos( radians( setLat ) ) * cos( radians( setLng ) - radians(nowLng) ) + sin( radians(nowLat) ) * sin( radians( setLat ) ) ) ) as distance;

위와 같이 하면 거리에 대한 결과가 나옵니다.

실제 사례를 들어서 확인해 보도록 하죠.. 

현재 위치
위도 : 37.486273
경도 : 126.995882

지정 위치
위도: 35.177286
경도: 126.900247

위 숫자를 넣어서 실행해 보도록 하겠습니다.

> select  (6371 * acos( cos( radians(37.486273) ) * cos( radians( 35.177286 ) ) * cos( radians( 126.900247 ) - radians(126.900247) ) + sin( radians(37.486273) ) * sin( radians( 35.177286 ) ) ) ) as distance;

결과는 다음과 같습니다.


소수점 2자리까지만 출력하기 위해 ROUND 함수를 처리해 봤습니다.

> select  ROUND(6371 * acos( cos( radians(37.486273) ) * cos( radians( 35.177286 ) ) * cos( radians( 126.900247 ) - radians(126.900247) ) + sin( radians(37.486273) ) * sin( radians( 35.177286 ) ) ), 2) as distance; 



256.75 Km라는 결과가 나옵니다.

위 예제를 잘 활용하면 MySQL을 활용하는 분들은 DB에서 거리 계산하는데 보다 쉬울 것 같네요.. 
소스를 가져갈 수 있도록 다시 한번 정리할께요..

 



Trackback 0 And Comment 0

모바일 어플리케이션의 성능 향상에 대해~

|



아이폰에 이어 안드로이드까지 요즘 모바일 어플리케이션 개발이 대세인 듯합니다. 

일단 기존 개발자들이 개발에 대한 접근이 쉽다는 장점이 있어 더욱 많아지는 것 같습니다. 
아이폰의 경우, Objective-C라는 언어를 별도로 학습해야 하지만 안드로이드는 Java 기반 개발자들에게는 별 어려움 없이 적응 할 수 있기도 하죠.

실제로 자료를 보면 점차 안드로이드 점유율이 높아질 거라 예상하고 있기도 하네요.

 
저희도 개발하면서 느끼는 거지만 모바일 어플리케이션은 왠지 모르게 느리다는 느낌이 있습니다.
게임이나 내부에서 동작하는 어플리케이션은 조금 낫지만 서버를 접속해야 하는 경우에 특히 이런 경우가 많습니다.

아무래도 3G 네트워크 환경에서의 속도 때문인데요..
실제 개발할 때는 보통 WIFI 환경에서 개발을 진행하기 때문에 전혀 문제가 없어 보이지만,
사용자들은 대부분 이동중에 스마트폰을 보는 경향이 있어 3G 환경이 많기 때문이죠..

3G 환경에서의 네트워크 속도는 제가 예전에 올린 다음 글을 참고하시면 될 것 같습니다.

2011/09/05 - [프로그래밍] - 3G 네트워크의 속도를 알아보자. 

그러면 과연 모바일 어플리케이션의 속도를 향상시키기 위해서는 어떻게 해야 할까요?
제 나름대로의 관점(전지적 미니 시점?)에서 접근해 보면 다음 그림처럼 3가지 요소를 고려해야 한다고 봅니다.
한번 정리해 볼께요..  


1. DB 최적화
기존 웹 사이트에서도 마찬가지지만 서비스의 성능에 가장 큰 영향을 주는 것이 바로 DB 입니다.
실제로 느린 사이트나 모바일 어플리케이션의 특징 중의 하나가 DB 최적화가 안되어 있다는 것이죠.

DB에서 Query를 하나 보냈는데 처리 시간이 1초 이상이 걸린다고 하면
당연히 사용자는 그만큼 오래 기다려야 하는 거겠죠..

DB 최적화에는 여러가지가 있습니다.
인덱스 구성을 최적화해서 Select 쿼리의 속도를 향상시키는 방법이 대표적이기도 한데요.
인덱스 라는 것이 Insert, Delete에 대해서는 반대로 속도를 떨어뜨리는 기능도 있기 때문에 적절한 설계가 필요하다고 봅니다.

또한 DB 자체의 설정을 통해 동시 접속 수를 어느 정도 설정하는 것도 필요하겠죠.. 

대부분 DB와 접속하기 위해 Web Server로 톰캣과 같은 WAS를 사용할 텐데요..
DB Connection Pool 관리도 중요한 내용이 되겠죠.  


그래서 일단 모바일에서 접근하는 모든 쿼리를 0.1초 이내의 응답시간에 처리할 수 있도록 구성하면
DB 최적화는 어느정도 되었다고 할 수 있을 것 같습니다.

2. Web Server 최적화
Web Server 최적화라고는 했지만 실질적으로는 모바일 어플리케이션에 제공하는 데이터 양을 줄이라는 것에 가깝습니다.
XML이나 간단한 문자열로 전송 데이터를 설계해서 개발하면 되겠죠..

웹서비스를  이용하기 위한 SOAP 등도 활용할 수 있겠으나 부가 정보들이 추가되는 경향이 있어 별로 추천하고 싶지는 않습니다.
작은 용량이나마 낭비되는 것은 줄이는 것이 바람직하지 않을까 해서요~

또한 Web Server의 동시 접속자 수도 체크해야 겠죠.. 
많이 사용하는 Apache의 경우 동시접속자 수가 500인가로 기본값으로 설정되어 있었던 것 같습니다. 
요즘 서버 성능이면 500 이상은 거뜬히 받아 들일 수 있기 때문에 이 값을 수정하는 것도 필요하겠죠..

3. 모바일 어플리케이션 자체 성능 향상
듀얼 코어 탑재 모바일 폰들이 나오고 있지만 아직도 PC에 비해 CPU 속도나 다른 성능이 떨어지는 것이 사실입니다.  
여기에서 지도 보여주고, 카메라 증강현실 넣고, OpenGL 이용한 그래픽 이것 저것 넣으면
자체 속도도 많이 떨어집니다.

제가 생각하기에는 모바일 어플리케이션 하나에서 모든 것을 하려고 하면 안될 것 같습니다.
자신의 핵심 기능에 집중하고 사람들이 그 기능 때문에 사용하도록 해야지..
이것 저것 많이 넣어둔다고 더 많은 사용자들이 쓰는 것은 아닌 것 같습니다.

모바일 어플리케이션 관련해서 발표할 사항이 있어 해당 내용들을 정리하다가 블로그에도 올려봅니다. 
주관적인 의견이기는 하지만 많이 참고하시기 바랍니다. 

 



Trackback 0 And Comment 0

MySQL 쿼리 결과를 파일로 저장하기

|




MySQL 쿼리 결과를 파일로 저장할 필요가 가끔 있습니다.
,를 구분자로 한 CSV 파일로 저장하면 엑셀에서 열어서 편집도 가능하죠..

간략하게 구문을 정리해 봅니다.

SELECT col1, col2, col3 INTO OUTFile '저장할파일명' FIELDS TERMINATED BY ',' FROM 테이블명;

INTO OUTFILE '저장할파일명' : SELECT 쿼리 결과를 저장할 파일을 지정합니다.
FIELDS TERMINATED BY '구분자': 각 Column을 구분할 구분자를 지정합니다.

예를 들어서 다음과 같이 쿼리하면 저장이 됩니다.
member 테이블에서 userid, name, email, status 필드 값을 추출해서 mini.csv로 저장합니다.

> select userid, name, email, status into outfile 'mini.csv' fields terminated by ',' from member;

이 경우, mini.csv 파일은 어디에 저장될까요?
기본적으로 mysql을 설치한 디렉토리에 저장됩니다.
제가 테스트 해보니 mysql 설치 디렉토리 하위의 data 폴더 밑에 DB이름으로 된 폴더 밑에 있더라구요.
즉, D:\dev\mysql\data\mini 하위에 mini.csv 파일이 저장되더군요.

다음과 같이 절대 경로로 입력해서 원하는 위치에 저장할 수도 있습니다.

윈도우의 경우
> select userid, name, email, status into outfile 'C:\mini.csv' fields terminated by ',' from member;

리눅스의 경우
> select userid, name, email, status into outfile '~/mini.csv' fields terminated by ',' from member;




Trackback 0 And Comment 0

MySQL 주요 명령어 모음

|




◈ mysql database 접속

-- root 유저 접속
mysql> mysql -uroot

-- mysql db 접속
mysql> use mysql;

-- database 조회
mysql> show databases;

-- table 조회
mysql> show tables;

-- table 구조 조회
mysql> desc db;



◈ root유저 비밀번호 변경

mysql> UPDATE user
            SET password = password('storm')
            WHERE user = 'root';
Query OK, 2 rows affected (0.28 sec)
Rows matched: 2  Changed: 2  Warnings: 0

user 테이블상에 root 사용자가 localhost와 host명으로 2개 등록 되어 있으므로
2row 의 비밀번호가 변경이 됩니다.

mysql> exit
Bye

C:mysqlbin>mysqladmin reload

-- 비밀번호를 입력해서 접속 해야 합니다.
C:mysqlbin>mysql -uroot -pstorm mysql



◈ database와 유저의 생성

-- database 생성(mysqladmin이용)
C:>mysqladmin -uroot -p create scott

-- database 생성(root유저로 접속)
C:mysqlbin>mysql -uroot -pstorm mysql

-- database 삭제
mysql> drop database scott;

-- database 생성
mysql> CREATE DATABASE scott;

-- user생성
mysql>insert into user (host,user,password) values('localhost','scott',password('tiger'));
mysql>insert into db values('localhost','scott','scott','y','y','y','y','y','y','y','y','y','y','y','y');

-- 변경사항 적용
mysql>flush privileges;

-- user삭제
mysql>DELETE FROM user WHERE user='scott' AND host='localhost';

-- 변경사항 적용
mysql>flush privileges;

-- grant문을 이용해서 사용자를 추가하는 방법
mysql>grant all on scott.* to scott@'localhost' identified by 'tiger';

-- 새로만든 scott db에 scott유저로 접속
C:mysqlbin>mysql -uscott -ptiger scott

-- script파일 실행(Oracle :start, @)
mysql>source C:scott.sql

-- 자주 사용하는 DB 생성 및 권한 설정 문
mysql> CREATE DATABASE scott DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
mysql> GRANT ALL PRIVILEGES ON *.* TO 'scott'@'localhost' IDENTIFIED BY 'tiger' WITH GRANT OPTION;
mysql>flush privileges;

◈ 원하는 만큼 데이터 가져오기

-- 앞에서 3개의 데이터를 조회함
mysql>SELECT empno, ename FROM emp LIMIT 3;

-- 2번째 이후의 데이터-부터 2개의 데이터를 조회함
mysql>SELECT empno, ename FROM emp LIMIT 2,2;



◈ Date And Time Functions

◈ String Functions

◈ Numeric Functions

◈ Cast Functions

◈ Other Functions

◈ Group Functions



◈ LEFT OUTER JOIN, RIGHT OUTER JOIN(Oracle : (+) )

mysql>SELECT b.deptno
           FROM emp a RIGHT OUTER JOIN dept b
          ON a.deptno = b.deptno



◈ SQL실행 결과를 파일로 저장

C:mysqlbin>mysql -uscott -ptiger scott > C:dump.txt
select * from emp;
select * from dept;
exit<!--"<-->



테이블 컬럼 타입


# 날짜 및 시간 관련 컬럼 타입

- DATE
   날짜를 표현하는 유형 [YYYY-MM-DD], 1000-01-01 ∼ 9999-12-31까지 나타낼 수 있

- DATETIME
   날짜와 시간을 표현하는 유형 [YYYY-MM-DD HH:MM:SS],  1000-01-01 00:00:00 ∼ 9999-12-31 23:59:59

- TIMESTAMP
   자동변경 컬럼 타입(4 Byte ),  1970-01-01 00:00:00부터 2037년 까지 표현

- TIME
   시간을 표현하는 유형 [HH:MM:SS],   839:59:59 ∼ 833:59:59 까지 표현

- YEAR
   년도를 표현하는 유형[기본적으로 4자리로 사용],  1901년 ∼ 2155년


# 문자 컬럼 타입

- CHAR(M)
   고정길이 문자열 컬럼,   M의 범위는 0 에서 255까지.

- VARCHAR(M)
   가변길이 문자열 컬럼,   M의 범위는 0 에서 255까지.

- TINYBLOB 또는 TINYTEXT
   최대길이 255개의 문자를 저장

- BLOB 또는 TEXT
   최대 길이가 63535인 문자를 저장

- MEDIUMBLOB 또는 MEDIUMTEXT
   최대 길이가 16777215인 문자를 저장

- LONGBLOB 또는 LONGTEXT
   최대 길이가 4294967295(4G)인 문자를 저장


* 참고

  - BLOB(Binary Large Object의 약자
  - BLOB타입은 대소문자를 구분하고 TEXT타입은 대소문자를 구분하지 않는점이 틀림
  - MySQL 3.23.2이번 버전에서는 BLOB와 TEXT컬럼에는 인덱스를 만들수 없다
  - BLOB와 TEXT컬럼의 저장시에 문자열 됫부분의 공백이 제거되지 않는다.
  - BLOB와 TEXT컬럼은 DEFAULT를 지정할 수 없다.


# 숫자 컬럼 타입

- TINYINT
    -128부터 127 까지의 정수형 타입,   부호가 없는 정수 0∼255까지 지원

- SMALLINT
    -32768부터 32767 까지의 정수형 타입,  부호가 없는 정수 0∼65535까지 지원

- MEDIUMINT
    -8388608부터 8388607 까지의 정수형 타입,   부호가 없는 정수 0∼16777215까지 지원

- INT 또는 INTEGER
   -2147483648부터 2147483647까지의 정수형 타입,  부호 없는 정수 0∼4294967295까지 지원

- BIGINT
   -9223372036854775808 부터 9223372036854775807 까지의 정수형 타입
   부호 없는 정수 0∼18446744073709551615까지 지원

- FLOAT(M,D)
   단정도 부동 소수점 실수,   -3.402823466E+38 ∼ -1.175494351E-38
   그리고 1.175494351E-38 ~ 3.402823466E+38까지  M은 숫자 전체의 길이, D는 소수점 자리수를 의미

- DOUBLE(M,D)
   2 배 정밀도를 가진 부동 소수점 실수,   -1.79769313486231517E+308 ∼ 2.22507385850720E+308



◈ 제약조건


# AUTO_INCREMENT(Oracle : Sequence)

-- 생성예제
mysql>CREATE TABLE sal(
           sal_id INT NOT NULL AUTO_INCREMENT,
           name VARCHAR(30) NOT NULL);

- AUTO_INCREMENT로 지정된 컬럼 타입은 숫자형이어야 한다 .
- AUTO_INCREMENT는 하나의 테이블에 하나의 컬럼만 지정할 수 있음
- AUTO_INCREMENT로 지정된 컬럼은 반드시 키 또는 인덱스로 정의되어야 한다.


# NOT NULL : NULL값을 허락하지 않음

# PRIMARY KEY : 중복된 데이터를 허락하지 않음, NOT NULL 조건도 추가

# UNIQUE : 중복돈 데이터를 허락하지 않음, NULL값을 허락한다.

# DEFAULT value : 디폴트 값을 지정함    


-- 예제..
mysql>CREATE TABLE emp2(
            id INT(3) NOT NULL,
            name VARCHAR(30) NOT NULL
            sal INT(5) DEFAULT 0,
            loc VARCHAR(50),
            PRIMARY KEY(id, name));



◈ SELECT 문을 이용하여 테이블 생성하기

-- Syntax
mysql>CREATE TABLE new_table SELECT column_list FROM old_table WHERE condition;

-- 예제
mysql>CREATE TABLE emp3 SELECT * FROM emp WHERE deptno = 10;



◈ 테이블 변경하기(ALTER TABLE)


# 컬럼 추가
mysql>ALTER TABLE table_name ADD COLUMN column_name data_type [FIRST|AFTER column_name];


# 컬럼 삭제
mysql>ALTER TABLE table_name DROP COLUMN column_name;


# 컬럼 변경
mysql>ALTER TABLE table_name CHANGE COLUMN  old_column  new_column  new_column_data_type;


# 테이블명 변경
mysql>ALTER TABLE old_table_name RENAME AS new_table_name;


# Primary Key 변경
mysql>ALTER TABLE table_name ADD PRIMARY KEY (column_list);

mysql>ALTER TABLE table_name DROP PRIMARY KEY;



◈ Database 백업


# mysqldump
mysqldump -uscott -ptiger scott > test.sql

# mysql dump restore

mysql -uscott -ptiger scott < test.sql

# BACKUP TABLE : 테이블을 데이터 파일로 백업함
mysql>BACKUP TABLE table_name[,tbl_name] TO '/path/directory'


# RESTORE TABLE : BACKUP TABLE로 백업한 데이터를 복구한다.  
mysql>RESTORE TABLE table_name[,tbl_name] FROM '/path/directory'



◈ 참고 (Oracle => MySQL 비교)


# NVL => IFNULL


# SELECT SYSDATE FROM DUAL => SELECT NOW();


# TO_CHAR => SELECT CAST(NOW() AS CHAR)

mysql은 CAST(expression AS data_type)또는 CONVERT(expression,type)로 형변환

oracle : SELECT TO_CHAR(SYSDATE,'RRRR-MM-DD') credate FROM DUAL
mysql : SELECT CAST(DATE_FORMAT(now(),'%Y-%m-%d') AS CHAR) credate;


# DECODE => CASE 예제..
SELECT CASE week WHEN 1 THEN '일요일' WHEN 2 THEN '월요일'
                  WHEN 3 THEN '화요일' WHEN 4 THEN '수요일'
                  WHEN 5 THEN '목요일' WHEN 6 THEN '금요일'
                  WHEN 7 THEN '토요일' END week
FROM STORM_COUNTER
WHERE year = 2002<!--"<-->


형변환과 관련하여 숫자도 다음과 같이 변경할 수 있습니다. 

SELECT CAST(-1 AS UNSIGNED)

-> 18446744073709551615

SELECT CAST(-1 AS SIGNED);

-> -1


어쨌든 유용하게 사용할 수 있는 mysql 명령어 모음입니다.
요즘 oracle보다 mysql을 좀 더 사용하다 보니.. 필요하더라구요~~

그럼. 좋은 하루 되세요~~






Trackback 0 And Comment 0
prev | 1 | next