14.18.5.1 memcached 응용 프로그램에 대한 기존의 MySQL 스키마 변경
memcached 인터페이스를 사용하기 위해 기존의 MySQL 스키마 또는 응용 프로그램을 수정하는 경우 memcached 응용 프로그램의 다음 사항을 고려하십시오.
공백이나 개행 문자는 ASCII 프로토콜 구분자로 사용되기 때문에 memcached의 키에 이러한 문자를 포함 할 수 없습니다. 공백이 포함 된 검색 값을 사용하는 경우,
add()
,set()
,get()
과 같은 호출이를 키로 사용하기 전에 공백이없는 값으로 변환 또는 해시합니다. 이러한 문자는 이론적으로 바이너리 프로토콜을 사용하는 프로그램에서 키로 허용되지만 다양한 클라이언트와의 호환성을 확보하기 위해 키에 사용되는 문자를 항상 제한합니다.InnoDB
테이블에 짧은 수치의 기본 키 열이있는 경우 정수를 문자열 값으로 변환하면 memcached의 고유의 검색 키로 사용할 수 있습니다. memcached 서버가 여러 응용 프로그램에서 사용되는 경우 또는 여러InnoDB
테이블과 함께 사용되는 경우 고유성을 유지하기 위해 이름 변경을 검토하십시오. 예를 들어, 숫자 앞에 테이블 또는 데이터베이스 이름과 테이블 이름을 지정합니다.참고MySQL 5.6.14 이후에서는
InnoDB
memcached 플러그인은 기본 키로INTEGER
가 정의 된 매핑 된InnoDB
테이블에 삽입 및 읽기를 지원합니다.memcached 인터페이스에서 쿼리를 실행하거나 저장하거나 데이터에 대해 파티션 된 테이블은 사용할 수 없습니다.
memcached 프로토콜은 숫자를 문자열로 전달합니다. 기반이되는
InnoDB
테이블에 값을 저장하는 경우 예를 들어,SUM()
과AVG()
같은 SQL 함수에 사용할 수있는 카운터를 구현하려면 다음과 같이합니다.예상되는 최대 수의 모든 자리 (또한 해당하는 경우는 마이너스 부호, 소수점 또는 둘 다에 대한 추가 문자)를 유지하기 위해 충분한 문자가
VARCHAR
컬럼을 사용합니다.컬럼 값을 사용하여 계산을 수행하는 모든 쿼리에서
CAST()
함수를 사용하여 문자열에서 정수 또는 기타 수치 형으로 변환합니다. 예 :- Alphabetic entries are returned as zero. select cast (c2 as unsigned integer) from demo_test; - Since there could be numeric values of 0, can not disqualify them. - Test the string values to find the ones that are integers, and average only those. select avg (cast (c2 as unsigned integer)) from demo_test where c2 between '0'and '9999999999'; - Views let you hide the complexity of queries. The results are already converted; - no need to repeat conversion functions and WHERE clauses each time. create view numbers as select c1 key, cast (c2 as unsigned integer) val from demo_test where c2 between '0'and '9999999999'; select sum (val) from numbers;
결과 집합의 알파벳의 값은
CAST()
를 호출하여 0으로 변환됩니다. 결과 집합의 행 수에 따라AVG()
등의 함수를 사용하는 경우, 숫자가 아닌 값을 제거하기 위해WHERE
절을 포함해야합니다.
키로서 사용하는
InnoDB
컬럼이 250 바이트보다 길어질 가능성이있는 경우 250 바이트 미만의 값이되도록 해시합니다.memcached 인터페이스에서 기존의 테이블을 사용하려면 그 테이블에 대한 항목을
innodb_memcache.containers
테이블에 정의합니다. memcached를 통해 중계되는 요청에 테이블을 기본값으로 지정하는 경우,name
컬럼에 값default
를 지정 후 MySQL Server를 다시 시작하여 변경 사항을 적용합니다. 다른 종류의 memcached 데이터에 여러 테이블을 사용하는 경우 사용자가 선택한name
값을 사용하여innodb_memcache.containers
테이블에 여러 항목을 설정 한 다음 응용 프로그램에서get @@
또는name
set @@
형식으로 memcached 요청을 발행하고 memcached API를 통해 후속 요청에 대해 사용되는 테이블을 전환합니다.name
사전 정의 된
test.demo_test
테이블 이외의 테이블을 사용하는 예는 예 14.23 "InnoDB + memcached 응용 프로그램을위한 테이블 및 컬럼 매핑 지정" 을 참조하십시오. 그런 테이블 필요한 레이아웃과 컬럼의 의미에 대해서는 섹션 14.18.7 "InnoDB memcached 플러그인의 내부 구조" 를 참조하십시오.memcached의 키 / 값 쌍에 의해 여러 MySQL 컬럼 값을 사용하려면 MySQL 테이블과 연관된
innodb_memcache.containers
항목에서value_columns
필드에 쉼표, 세미콜론, 공백 또는 파이프 문자로 구분 된 여러 컬럼 이름을 지정합니다. 예를 들어,col1,col2,col3
또는col1|col2|col3
과 같이됩니다.컬럼 값을 파이프 문자를 구분 기호로 사용하여 단일 문자열이되도록 연결 한 후에, 그 문자열을 memcached의
add
또는set
호출에 전달합니다. 문자열은 다양한 컬럼에 자동으로 언팩됩니다. 개별get
호출은 역시 파이프 구분자에 의해 구분되는 여러 컬럼 값을 포함하는 단일 문자열을 반환합니다. 응용 프로그램 언어에 따라 적절한 구문을 사용하여이 값을 풉니 다.
예 14.23 InnoDB + memcached 응용 프로그램을위한 테이블 및 컬럼 매핑 지정
여기에서 데이터 조작을 위해 InnoDB
memcached 플러그인을 사용하는 MySQL 애플리케이션을 위해 사용자 자신의 데이터를 사용하는 방법의 예를 보여줍니다.
먼저 일부 국가 데이터를 보유하는 테이블을 설치합니다. 데이터는 인구 미터법으로 표시 면적 오른쪽 또는 왼쪽 어느 쪽이 운전 하는지를 나타내는 'R'
또는 'L'
입니다.
use test; CREATE TABLE`multicol` ( `country` varchar (128) NOT NULL DEFAULT '', `population` varchar (10) DEFAULT NULL, `area_sq_km` varchar (9) DEFAULT NULL, `drive_side` varchar (1) DEFAULT NULL, `c3` int (11) DEFAULT NULL, `c4` bigint (20) unsigned DEFAULT NULL, `c5` int (11) DEFAULT NULL, PRIMARY KEY (`country`) ) ENGINE = InnoDB DEFAULT CHARSET = latin1;
여기에서 InnoDB
memcached 플러그인이 테이블에 액세스하는 방법을 인식하도록이 테이블 디스크립터를 만듭니다.
CONTAINERS
테이블의 샘플 항목은name
컬럼이'aaa'
로 다른 식별자'bbb'
를 설치합니다. 사용하는 모든 memcached 응용 프로그램에 단일 마스터 테이블을 작성한 경우 ID를'default'
하고 테이블을 전환위한@@
요청을 건너 뜁니다.test.multicol
테이블을 지정합니다. 스키마 이름은 하나의 컬럼에 저장된 테이블 이름은 다른 컬럼에 저장됩니다.키 컬럼이 고유
country
입니다. 이 컬럼은 위의 테이블을 만들 때 기본 키에 지정된 때문에 여기에 인덱스 이름'PRIMARY'
도 지정합니다.하나의 복합 데이터를 단일 컬럼에 유지하는 대신 데이터를 3 개의 테이블 컬럼에 분할하기 때문에 값을 저장하거나 검색 할 때 사용되는 컬럼의 쉼표로 구분 된 목록을 지정합니다.
또한 플래그 만료 및 CAS 값은 샘플 테이블
demo.test
설정에 따라 대응하는 컬럼을 지정합니다. 이 값은InnoDB
memcached 플러그인을 사용하는 응용 프로그램은 보통 그다지 중요하지 않습니다. MySQL 데이터 동기화를 유지하기 위해 데이터가 만료되거나 오래되거나하는 것을 걱정할 필요가 없기 때문입니다.
insert into innodb_memcache.containers (name, db_schema, db_table, key_columns, value_columns, flags, cas_column, expire_time_column, unique_idx_name_on_key) values ( 'bbb', 'test', 'multicol', 'country', 'population, area_sq_km, drive_side' 'c3', 'c4', 'c5', 'PRIMARY'); commit;
여기서 프로그램에서이 테이블에 액세스하는 방법을 보여주는 샘플 Python 프로그램을 나타냅니다.
모든 데이터 조작은 memcached 인터페이스를 통해 실행되기 때문에 데이터베이스 권한이 필요하지 않습니다. 알아야 할 것은 memcached 데몬이 로컬 시스템에서 수신하는 포트 번호뿐입니다.
임의의 여러 나라의 샘플 값을로드합니다. (위키 백과에서 면적 및 인구의 숫자입니다.)
프로그램에서
multicol
테이블을 사용하기 위해@@
표기를 사용하여 더미GET
또는SET
요청을 할switch_table()
함수를 호출합니다. 요청의 이름은bbb
, 이것은innodb_memcache.containers.name
에 저장되어있는 값입니다. (실제 응용 프로그램에서는 더 설명적인 이름을 사용합니다.이 예제에서는GET @@...
요청에서 테이블 이름이 아닌 테이블 식별자를 지정하는 것을 보여줍니다.데이터를 삽입하고 쿼리를 실행하기위한 유틸리티 함수는
ADD
또는SET
요청에 의해 MySQL에 보내 Python 데이터 구조를 파이프로 구분 된 값으로 변환하고GET
요청에 의해 반환 된 파이프로 구분 된 값을 풀고위한 방법을 보여줍니다. 이 특별한 처리는 단일 memcached 값을 여러 MySQL 테이블 컬럼에 매핑하는 경우에만 필요합니다.
import sys, os import memcache def connect_to_memcached () : memc = memcache.Client ( '127.0.0.1:11211', debug = 0); print "Connected to memcached." return memc def banner (message) : print print "="* len (message) print message print "="* len (message) country_data = ( "Canada", "34820000", "9984670", "R") ( "USA", "314242000" "9826675", "R") ( "Ireland", "6399152", "84421", "L") ( "UK", "62262000", "243610", "L") ( "Mexico", "113910608" "1972550", "R") ( "Denmark", "5543453", "43094", "R") ( "Norway", "5002942", "385252", "R") ( "UAE", "8264070", "83600", "R") ( "India" "1210193422", "3287263", "L") ( "China" "1347350000", "9640821", "R") ] def switch_table (memc, table) : key = "@@"+ table print "Switching default table to '"+ table + "'by issuing GET for '"+ key + "'" result = memc.get (key) def insert_country_data (memc) : banner ( "Inserting initial data via memcached interface") for item in country_data : country = item [0] population = item [1] area = item [2] drive_side = item [3] key = country value = "|".join (population, area, drive_side) print "Key ="+ key print "Value ="+ value if memc.add (key, value) : print "Added new key, value pair." else : print "Updating value for existing key." memc.set (key, value) def query_country_data (memc) : banner ( "Retrieving data for all keys (country names)") for item in country_data : key = item [0] result = memc.get (key) print "Here is the result retrieved from the database for key"+ key + ":" print result (m_population, m_area, m_drive_side) = result.split ( "|") print "Unpacked population value :"+ m_population print "Unpacked area value :"+ m_area print "Unpacked drive side value :"+ m_drive_side if __name__ == '__main__': memc = connect_to_memcached () switch_table (memc "bbb") insert_country_data (memc) query_country_data (memc) sys.exit (0)
여기에 표시된 일부 SQL 쿼리 스크립트가 실행 된 뒤의 MySQL 데이터의 상태를 나타내고 SQL을 통해 동일한 데이터에 직접 액세스하거나 적절한 MySQL 커넥터 또는 API 를 사용하는 모든 언어로 작성된 응용 프로그램에서 액세스 할 방법을 보여줍니다.
테이블 디스크립터 'bbb'
가 있기 때문에 memcached 요청 GET @bbb
을 발행하면 multicol
테이블로 전환 할 수 있습니다.
mysql: use innodb_memcache; Database changed mysql: select * from containers; +------+-----------+-----------+-------------+----------------------------------+-------+------------+--------------------+------------------------+ | name | db_schema | db_table | key_columns | value_columns | flags | cas_column | expire_time_column | unique_idx_name_on_key | +------+-----------+-----------+-------------+----------------------------------+-------+------------+--------------------+------------------------+ | aaa | test | demo_test | c1 | c2 | c3 | c4 | c5 | PRIMARY | | bbb | test | multicol | country | population,area_sq_km,drive_side | c3 | c4 | c5 | PRIMARY | +------+-----------+-----------+-------------+----------------------------------+-------+------------+--------------------+------------------------+ 2 rows in set (0.01 sec)
스크립트를 실행 한 뒤, 데이터는 multicol
테이블에 기존의 MySQL 쿼리 또는 DML 문에서 사용할 수 있습니다.
mysql: use test; Database changed mysql: select * from multicol; +---------+------------+------------+------------+------+------+------+ | country | population | area_sq_km | drive_side | c3 | c4 | c5 | +---------+------------+------------+------------+------+------+------+ | Canada | 34820000 | 9984670 | R | 0 | 11 | 0 | | China | 1347350000 | 9640821 | R | 0 | 20 | 0 | | Denmark | 5543453 | 43094 | R | 0 | 16 | 0 | | India | 1210193422 | 3287263 | L | 0 | 19 | 0 | | Ireland | 6399152 | 84421 | L | 0 | 13 | 0 | | Mexico | 113910608 | 1972550 | R | 0 | 15 | 0 | | Norway | 5002942 | 385252 | R | 0 | 17 | 0 | | UAE | 8264070 | 83600 | R | 0 | 18 | 0 | | UK | 62262000 | 243610 | L | 0 | 14 | 0 | | USA | 314242000 | 9826675 | R | 0 | 12 | 0 | +---------+------------+------------+------------+------+------+------+ 10 rows in set (0.00 sec) mysql: desc multicol; +------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+---------------------+------+-----+---------+-------+ | country | varchar(128) | NO | PRI | | | | population | varchar(10) | YES | | NULL | | | area_sq_km | varchar(9) | YES | | NULL | | | drive_side | varchar(1) | YES | | NULL | | | c3 | int(11) | YES | | NULL | | | c4 | bigint(20) unsigned | YES | | NULL | | | c5 | int(11) | YES | | NULL | | +------------+---------------------+------+-----+---------+-------+ 7 rows in set (0.01 sec)
숫자로 취급되는 컬럼의 길이를 정의 할 때 필요한, 소수점 부호 문자 선행 제로 등을 유지하기에 충분한 크기를 고려합니다. VARCHAR
같은 문자열 컬럼에서 값이 너무 길면, 그 값은 일부 문자를 삭제하고 잘리고 잘못된 값이 생성 될 수 있습니다.
SQL 쿼리를 사용하여 country
키 컬럼뿐만 아니라 임의의 컬럼을 사용하여 계산 및 테스트를 수행하고 보고서를 작성할 수 있습니다. (이 예에서는 소수 국가의 데이터 만 사용하고 있기 때문에, 수치는 예시만을 목적으로하고 있습니다.) 여기에서 오른쪽을 운전하는 국가의 평균 인구와 이름이 "U"로 시작하는 나라 평균 면적을 구합니다.
mysql: select avg(population) from multicol where drive_side = 'R'; +-------------------+ | avg(population) | +-------------------+ | 261304724.7142857 | +-------------------+ 1 row in set (0.00 sec) mysql: select sum(area_sq_km) from multicol where country like 'U%'; +-----------------+ | sum(area_sq_km) | +-----------------+ | 10153885 | +-----------------+ 1 row in set (0.00 sec)
population
및 area_sq_km
컬럼은 강력하게 형식화 된 수치 데이터가 아닌 문자 데이터를 저장하기 위해 avg()
나 sum()
등의 함수는 먼저 각각의 값을 숫자로 변환합니다. 이 기술은 <
나 >
등의 연산자는 작동하지 않고 예를 들어, 문자 기반 값을 비교할 때 9 > 1000
되고, 이것은 ORDER BY population DESC
등의 어구에서 예상되는 결과가 없습니다. 가장 정확한 형태 처리하려면 숫자 열을 적절한 형식으로 캐스팅 뷰를 쿼리합니다. 이 기법은 매우 간단한 SELECT *
쿼리를 데이터베이스 응용 프로그램에서 실행할 수 캐스트 필터링 및 정렬이 올바르게됩니다. 여기서 인구의 상위 3 개국을 내림차순으로 요청하는 쿼리를 실행하는 뷰를 작성합니다. 결과는 항상 multicol
테이블에서 최신 데이터를 반영하여 인구와 면적은 항상 숫자로 처리됩니다.
mysql: create view populous_countries as select country, cast(population as unsigned integer) population, cast(area_sq_km as unsigned integer) area_sq_km, drive_side from multicol order by cast(population as unsigned integer) desc limit 3; Query OK, 0 rows affected (0.01 sec) mysql: select * from populous_countries; +---------+------------+------------+------------+ | country | population | area_sq_km | drive_side | +---------+------------+------------+------------+ | China | 1347350000 | 9640821 | R | | India | 1210193422 | 3287263 | L | | USA | 314242000 | 9826675 | R | +---------+------------+------------+------------+ 3 rows in set (0.00 sec) mysql: desc populous_countries; +------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+---------------------+------+-----+---------+-------+ | country | varchar(128) | NO | | | | | population | bigint(10) unsigned | YES | | NULL | | | area_sq_km | int(9) unsigned | YES | | NULL | | | drive_side | varchar(1) | YES | | NULL | | +------------+---------------------+------+-----+---------+-------+ 4 rows in set (0.02 sec)