Download tbl_name

Document related concepts
no text concepts found
Transcript
MySQL Tutorial
[email protected]
1
(ver. 1.0)
1. MySQL ์„ค์น˜
2
Linux์— ์„ค์น˜
โ€“ MySQL ์ œ๊ณต์˜ RPM ์„ ์‚ฌ์šฉํ•  ๊ฒƒ.
โ€ข MySQL binary๊ฐ€ ๋น ๋ฅด๊ฒŒ ๋ฐœ์ „/๋ณ€๊ฒฝ
โ€ข ํŒŒ์ผ ์œ„์น˜์ƒ์— ๋‹ค์†Œ๊ฐ„ ์ฐจ์ด
โ€“ RPM ํŒŒ์ผ:
โ€ข MySQL-server-VERSION.i386.rpm,
โ€ข MySQL-Max-VERSION.i386.rpm, and
โ€ข MySQL-client-VERSION.i386.rpm.
โ€“ ์„ค์น˜:
โ€ข rpm -i MySQL-server-VERSION.i386.rpm MySQLclient-VERSION.i386.rpm
โ€ข ๏ƒจ mysqld (MySQL server)๋ฅผ startํ•˜๊ณ , ๋™์‹œ์—
/etc/init.d/ ์— ์ ์ ˆํ•œ ํ•ญ๋ชฉ์„ ์ƒ์„ฑ์‹œํ‚ด (๏ƒ ์‹œ์Šคํ…œ์ด ์ผœ
์ง€๋ฉด ์ž๋™์œผ๋กœ ์„œ๋ฒ„๋ฅผ start)
3
โ€ข ์ •๋ฆฌ:
Windows์— ์„ค์น˜
โ€“ IF (๊ธฐ์กด์˜ MySQL์ด ์žˆ์œผ๋ฉด) THEN ์ •์ง€์‹œํ‚ฌ ๊ฒƒ:
mysqladmin -u root -p shutdown
โ€“ ElseIF (MySQL์ด ์„œ๋น„์Šค๋กœ์„œ ์„ค์น˜) THEN ์ •์ง€์‹œํ‚ฌ ๊ฒƒ:
mysqld --remove
โ€“ ElseIF (Graphical tool์„ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•œ๋‹ค๋ฉด) ์ •์ง€์‹œํ‚ฌ ๊ฒƒ:
โ€ข ์„ค์น˜
โ€“ control panel>Admin Tool SVC> SVCs Manager์—์„œ ์„œ๋น„์Šค ์ œ๊ฑฐ
โ€“ setup.exe ๋˜๋Š” MSI installer๋ฅผ ์ด์šฉ
โ€ข options file์„ ์ƒ์„ฑ์‹œํ‚ฌ ๊ฒƒ.
โ€ข ๋ช…๋ น์–ด ์ค„์—์„œ
โ€“ MySQL ์„œ๋ฒ„์˜ ๋””๋ ‰ํ† ๋ฆฌ (c:\mysql\bin)๋กœ ๊ฐ„ ํ›„ Type:
mysqld-max --standalone
โ€ข ๏ƒ  startup ๋ฉ”์‹œ์ง€. ๋ณ„ ๋ฌธ์ œ๊ฐ€ ์—†๋‹ค๋ฉด MySQL์„ ์„œ๋น„์Šค๋กœ์„œ ์„ค์น˜
โ€“ ์ด์šฉํ•˜๊ณ ์ž ํ•˜๋Š” server executable์„ ์ž…๋ ฅ:
โ€ข ์ฐธ๊ณ 
mysqld-max --install (์ถ”์ฒœ)
โ€“ Perl engine์„ ์„ค์น˜ํ•  ๊ฒƒ.
โ€ข www.activestate.com/Products/ActivePerl/
โ€ข ActivePerl comes as an MSI file. Download ํ›„ ์„ค์น˜.
4
Installing on OS X
โ€ข (์ƒ๋žต)
5
Configuring Your System
โ€“ (recommend)
โ€ข InnoDB table ์‚ฌ์šฉ
โ€ข binary logging ์„ ์ผœ ๋†“์„ ๊ฒƒ.
โ€ข slow query logging์„ ์ผœ ๋†“์„ ๊ฒƒ.
โ€“ help you optimize your applications.
โ€“ (options file: configuration value ์ €์žฅ)
โ€ข Windows์—์„œ,
โ€“ Global options file can be located either in your
Windows directory and named my.ini or in c:\my.cnf.
โ€“ (๊ถŒ๊ณ ) my.ini ์‚ฌ์šฉ (๏ƒŸ.cnf๋Š” ๊ฐ„ํ˜น ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ด์šฉ)
โ€ข Unix-like ์šด์˜์ฒด์ œ์˜ ๊ฒฝ์šฐ,
โ€“ Global options file์€ ๋ณดํ†ต /etc/my.cnf.
โ€“ ํ•˜๋‚˜์˜ ์‹œ์Šคํ…œ์— ์—ฌ๋Ÿฌ ์„œ๋ฒ„ ์šด์˜ ์‹œ: ์„œ๋ฒ„ ๋ณ„ ์ •๋ณด๋ฅผ my.cnf
์˜ data directory์— ์ง€์ •.
โ€“ ๊ฐœ๋ณ„ ์‚ฌ์šฉ์ž๋ณ„๋กœ ๋‹ค๋ฅด๊ฒŒ ์ €์žฅํ•˜๋Š” ๊ฒฝ์šฐ: ~/.my.cnf
6
Listing 1.1 Suggested Options File
[mysqld]
# turn on binary logging and slow query logging
log-bin
log-slow-queries
# InnoDB config
# This is the basic config as suggested in the manual
# Datafile(s) must be able to hold your data and indexes.
# Make sure you have enough free disk space.
๋ฉ”๋ชจ๋ฆฌ x 50%~80%
innodb_data_file_path = ibdata1:10M:autoextend = buffer pool size x 25%
# Set buffer pool size to
-- additional memory pool size
===> log file size
# 50 - 80 % of your computer's memory
-- log buffer-size
set-variable = innodb_buffer_pool_size=70M
set-variable = innodb_additional_mem_pool_size=10M
# Set the log file size to about
# 25 % of the buffer pool size
set-variable = innodb_log_file_size=20M
set-variable = innodb_log_buffer_size=8M
# Set ..flush_log_at_trx_commit to 0 if you can afford losing
# some last transactions
innodb_flush_log_at_trx_commit=1
7
Checking Your System Works
โ€ข ๊ธฐ๋ณธ์‚ฌํ•ญ
โ€ข - mysql -u root
โ€ข PATH ์ง€์ •
Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL
connection id is 4 to server version: 4.1.0-alpha-max-debug-logType 'help;'
or '\h' for help. Type '\c' to clear the buffer.
โ€“ If you get a message similar to
ERROR 2003: Can't connect to MySQL server on 'localhost' (10061)
โ€“ = โ€œMySQL server๊ฐ€ ์ˆ˜ํ–‰๋˜์ง€ ์•Š๋Š”๋‹คโ€
โ€“ ๏ƒ  ์‹œ์Šคํ…œ์„ ์žฌ ์‹œ๋™ํ•˜๊ฑฐ๋‚˜ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜๋™ ์‹œ๋™:
โ€ข - mysqld --standalone
8
โ€“ Root Password ์„ค์ •
โ€“ set password for root@localhost=password('your password');
โ€ข Log out (\q) ํ›„ ๋‹ค์‹œ log-in ๋‹จ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด:
โ€“ mysql -u root -p
โ€“ Anonymous Account ์‚ญ์ œ
use mysql;
delete from user where User='';
delete from db where User='';
flush privileges;
9
์ผ์ƒ ์‚ฌ์šฉ (Basic use) Account ์„ค์ •
โ€“ ์ผ๋ฐ˜ ์‚ฌ์šฉ์„ ์œ„ํ•œ account ์ƒ์„ฑ:
grant (create, create temporary tables,
delete, execute, index, insert, lock tables,
select, show databases, update)
on *.*
to username identified by 'password';
10
2. Quick Tour
11
MySQL Directory ๊ตฌ์กฐ
โ€ข (MySQL ํŒŒ์ผ์˜ default ์œ„์น˜)
โ€“ Base location
โ€ข Unix :
/usr/local/mysql
โ€ข Windows: C:\mysql.
โ€“ File system
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
bin: MySQL server, client ๋ฐ ๊ธฐํƒ€์˜ ์œ ์šฉํ•œ compiled program ์ˆ˜๋ก
scripts: Perl scripts ์ˆ˜๋ก
data: ์‹ค์ œ์˜ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ์ดํ„ฐ ์ˆ˜๋ก
docs (Linux) or Docs (Windows)
sql-bench (Linux) or bench (Windows): benchmarking suite.
โ€“ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š๋Š” ๋‹ค๋ฅธ ๋””๋ ‰ํ† ๋ฆฌ
โ€ข include : header files,
โ€ข lib :
libraries used by MySQL,
โ€ข share : MySQL's error messages, and examples (only in
Windows, libmysql DLL์„ ์ด์šฉํ•˜๋Š” ์˜ˆ์ œ).
โ€ข ** MySQL์— link๋˜๋Š” ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ (์˜ˆ: PHP) ์„ค์น˜ ์‹œ์— ๊ทธ ์œ„์น˜๋ฅผ ์•„
๋Š” ๊ฒƒ์ด ์œ ์šฉ.
12
Executables ๊ฐœ์š”
โ€ข MySQL executables๋ž€?
โ€“ bin and scripts directories
โ€“ bin directory
โ€ข mysqld (๋˜๋Š” ๊ด€๋ จ ๋ณ€ํ˜• ๋ชจ๋“ˆ)= MySQL server program
โ€ข mysql = MySQL monitor = command-line client.
โ€ข ๊ธฐํƒ€์˜ ์ฃผ์š” ํ”„๋กœ๊ทธ๋žจ
โ€“
โ€“
โ€“
โ€“
โ€“
mysqladmin: ๊ด€๋ฆฌ ๊ธฐ๋Šฅ
myisamchk: damaged MyISAM table์„ check/repair.
mysqldump: database์˜ backup
mysqlbinlog: binary log์˜ ๋‚ด์šฉ์„ read. (disaster recovery ๋“ฑ).
mysqlshow: databases ๋ฐ table ์ •๋ณด๋ฅผ ๋ณด์—ฌ์คŒ
โ€“ scripts directory
โ€ข = interpreted Perl scripts (cf.bin ๋””๋ ‰ํ† ๋ฆฌ: compiled program)
โ€ข ์ค‘์š”ํ•œ script
โ€“ Mysqlhotcopy ; database์˜ back up.
13
User Interface ๊ฐœ์š”
โ€ข 3๊ฐ€์ง€ ์ฃผ์š” UI
โ€“ mysql (=MySQL monitor),
โ€ข command-line interface
โ€ข ๊ธฐ๋ณธ ์„ค์น˜ ์‹œ์— ์ƒ์„ฑ๋จ
โ€“ MySQL Control Center (MySQLCC),
โ€ข (Qt windowing toolkit์œผ๋กœ ์ž‘์„ฑ๋œ) GUI
โ€ข cross-platform
โ€ข ์‰ฝ๊ฒŒ downloadํ•ด์„œ ์„ค์น˜
โ€“ phpMyAdmin.
โ€ข Web ๊ธฐ๋ฐ˜ interface. (Web application ๊ฐœ๋ฐœ์— ํŽธ๋ฆฌ)
โ€ข ์‰ฝ๊ฒŒ download ์„ค์น˜
14
MySQL Monitor ๋ง›๋ณด๊ธฐ
โ€ข MySQL์— ์—ฐ๊ฒฐ:
โ€ข mysql -u username -p
โ€“ (์Šค์œ„์น˜)
โ€ข mysql -h hostname -u username -p /* ํ˜ธ์ŠคํŠธ ์ง€์ • */
โ€ข mysql --i-am-a-dummy -u root -p ๏ƒ  ๋ช…๋ น์˜ค๋ฅ˜์— ๋”ฐ๋ฅธ damage ์˜ˆ๋ฐฉ
โ€ข --i-am-a-dummy option = --safe-updates.
โ€“ SHOW command:
โ€ข
โ€ข
โ€ข
โ€ข
show databases; /* semicolon ์œ ์˜ */
use databasename;
show tables;
describe tablename;
โ€“ \ (backslash)๋กœ ์‹œ์ž‘๋˜๋Š” ๋ช…๋ น์–ด
โ€ข \q, \h (for help)
โ€ข Command script
โ€“ ์ˆ˜ํ–‰:
โ€ข source filename
/* MySQL monitor์—์„œ */
โ€ข mysql -u username -p < filename
/* MySQL monitor์— log-in๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ */ 15
3. DB Design Crash Course
16
Database ์šฉ์–ด์™€ ๊ฐœ๋…
โ€ข Entities and Relationships
โ€“ Entities
โ€ข = ์‹ค์ œ ์„ธ๊ณ„์—์„œ์˜ ์‚ฌ๋ฌผ (things in the real world).
๏ƒ  ๊ทธ ์ •๋ณด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•œ๋‹ค.
โ€ข ์˜ˆ: employees, departments
โ€“ Relationships
โ€ข = entity๋“ค ๊ฐ„์˜ link
โ€ข ์˜ˆ: Works-for; an employee works for a department.
โ€ข different degrees of relationship
โ€“ one-to-one, one-to-many many-to-many
17
โ€ข Relations or Tables
โ€“ relational database management system (RDBMS)๋ž€
โ€“ = supports databases that consist of a set of relations.
โ€“ ์—ฌ๊ธฐ์„œ relation = a table of data. (์˜ˆ: excelํŒŒ์ผ, Fig 3.2)
โ€ข Columns or Attributes
โ€“ column and attribute ์ด ์ข…์ข… ํ˜ผ์šฉ๋˜์ง€๋งŒ
โ€“ a column is really part of a table, whereas an attribute
relates to the real-world entity that the table is modeling.
โ€ข In Figure 3.2 โ€ฆ
โ€ข Rows = Records = Tuples
โ€“ โ€ฆ
18
โ€ข Keys
โ€“ A superkey
โ€ข = table ๋‚ด์—์„œ row๋ฅผ ์‹๋ณ„ํ•ด ๋‚ด๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” a column (or set of
columns) .
โ€ข (์˜ˆ) employee table์—์„œ <employeeID, name> ๋˜๋Š” <employeeID,
name, job, departmentID>๋ฅผ ํ†ตํ•ด row๋ฅผ ๊ตฌ๋ณ„ ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด๋“ค ๊ฐ๊ฐ์ด
super keys
โ€“ A key = a minimal superkey.
โ€ข employee table์—์„œ employee๋ฅผ name ๋˜๋Š” employeeID์— ์˜ํ•ด ๊ตฌ๋ณ„ํ• 
์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ด๋“ค ๋ชจ๋‘ key๊ฐ€ ๋œ๋‹ค.
โ€“ Candidate keys
โ€ข = keys from which we will choose the primary key.
โ€ข ๊ทธ๋Ÿฌ๋‚˜ ์‹ค์ œ๋กœ๋Š” We need only the employeeID to identify a row. ์ฆ‰,
minimal superkey (a minimized set of columns that can be used to
identify a single row)์ธ employeeID๊ฐ€ key๊ฐ€ ๋œ๋‹ค.
โ€“ primary key
โ€ข = the column or set of columns that we will use to identify a single
row from within a table. ์—ฌ๊ธฐ์„œ๋Š” employeeID๋ฅผ primary key๋กœ ํ•œ๋‹ค.
โ€“ Foreign keys
โ€ข represent the links between tables.
19
โ€ข Functional Dependencies
โ€“ normalization process ์ดํ•ด๋ฅผ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ฐœ๋…
โ€“ ํ…Œ์ด๋ธ” ์ƒ์—์„œ column A์™€ column B ์‚ฌ์ด์— functional dependency
(A๏ƒ  B) = the value of column A determines the value of column B.
โ€ข ์˜ˆ: employee table์—์„œ employeeID functionally determines the name
(and all the other attributes in this particular example).
โ€ข Schemas
โ€“ = the structure (=design/ blueprint/ form) of the database without
any data in it.
โ€“ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œํ˜„:
โ€ข employee(employeeID, name, job,
โ€“ ๋ณธ์„œ์—์„œ์˜ convention:
)
โ€ข a solid underline = the attributes that represent the primary key
โ€ข a broken underline = any attributes that represent foreign keys.
โ€ข a solid and a broken underline = Primary keys that are also foreign
keys
20
Database ์„ค๊ณ„ ์›์น™
โ€ข Database์„ค๊ณ„ ์‹œ ๊ณ ๋ คํ•  ์ค‘์ ์‚ฌํ•ญ:
โ€“
โ€“
โ€“
โ€“
Entity; ๋Œ€์ƒ์ด ๋˜๋Š” ์ •๋ณด๋Š” ๋ฌด์—‡? ์ฆ‰, things or entities?
Relation; โ€ฆ
์›ํ•˜๋Š” (queryํ•˜๋ ค๋Š” )์ •๋ณด? =โ€œ๋ชจ๋ธ๋ง ํ•˜๋ ค๋Š” ์‚ฌ์—…์˜ business rulesโ€
์ •๊ทœํ™”; redundancy and data anomalies์™€ ๊ฐ™์€ ๊ตฌ์กฐ์  ๋ฌธ์ œ์˜ ํ•ด๊ฒฐ!!
โ€ข ํšจ์œจ์„ฑ (tuning/optimizing)๊ณผ ๊ด€๋ฆฌ์„ฑ
โ€ข Redundancy Versus Loss of Data
โ€“ Redundancy = ์—ฌ๋Ÿฌ row or table์—์„œ ๋ฐ˜๋ณต๋˜๋Š” data.
โ€“ (Imagine:)
โ€ข employeeDepartment(employeeID, name, job, departmentID,
departmentName)
โ€ข Figure 3.3. ; This schema design leads to redundantly storing the
department name over and over.
โ€ข We can change this design as shown here:
employee(employeeID, name, job,
department(departmentID, name)
)
โ€ข ๏ƒ  ์ €์žฅ ๊ณต๊ฐ„์„ ์ค„์ด๊ณ  ๊ธฐํƒ€์˜ ๋ช‡ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•จ.
โ€“ Schema ๊ฐœ์„  ์‹œ ์—ผ๋‘์— ๋‘˜ goal;
โ€ข โ€œreducing repetition of data without losing any informationโ€.
21
โ€ข Anomalies
โ€“ (3 types)
โ€“ ๏ƒŸ flawed schema์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ insert/delete/updateํ•  ๋•Œ ๋ฐœ์ƒ . (Fig 3.3.)
โ€“ Insertion Anomalies
โ€ข ๊ธฐ์กด์˜ ํ•ญ๋ชฉ๊ณผ ์ƒ์ถฉ๋˜๋Š” (match๋˜์ง€ ์•Š๋Š”) ๋ฐ์ดํ„ฐ๋ฅผ insertํ•˜๋Š” ๊ฒฝ์šฐ
โ€ข (์˜ˆ) enter an employee as working for Department 42, Development? ์–ด๋Š row๊ฐ€ ๋งž๋Š”
์ง€ ํ™•์‹ค์น˜ ์•Š์Œ.
โ€“ Deletion Anomalies
โ€ข (์˜ˆ) all the employees of Department 128 leave on the same day. ์ด๋•Œ ์ด๋“ค ๋ชจ๋“  record
๋ฅผ delete ํ•˜๋ฉด ๋” ์ด์ƒ Department 128๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๊ฒŒ ๋œ๋‹ค.
โ€“ Update Anomalies
โ€ข (์˜ˆ) Department 128 decides to change its name to Emerging Technologies.
์ž ๋ชจ๋‘๋ฅผ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š”๋ฐ ๋งŒ์•ฝ ๋ˆ„๋ฝ๋˜๋Š” ์ž๊ฐ€ ์ƒ๊ธธ ๋•Œ update anomaly.
์ด๋•Œ ๊ด€๋ จ
โ€ข Null Values
โ€“ = avoid schema designs that have large numbers of empty attributes.
โ€“ ์˜ˆ: 100๋ช…์ค‘ 1~2๋ช…๋งŒ ํ•ด๋‹น๋˜๋Š” ์‚ฌํ•ญ์ด ์žˆ์„ ๋•Œ ๋Œ€๋ถ€๋ถ„์ด NULL์ด๋ฏ€๋กœ ์˜คํžˆ๋ ค ๊ทธ ์‚ฌํ•ญ์„
๊ธฐ์ˆ ํ•˜๋Š” ์ƒˆ๋กœ์šด table์„ ์ถ”๊ฐ€ํ•˜๋Š” ํŽธ์ด ๋‚ซ๋‹ค.
22
์ •๊ทœํ™”
โ€ข Normalization
โ€“ = DB์„ค๊ณ„ ๊ฒฐํ•จ ์ œ๊ฑฐ ์ ˆ์ฐจ ๏ƒŸ breaking tables into smaller tables
โ€“ 1์ฐจ normal form > 2์ฐจ NF > โ€ฆ
โ€ข "Normalization is about the key, the whole key, and nothing
but the key."
โ€ข 2NF; attributes must depend on the whole key.
โ€ข 3NF; attributes must depend on nothing but the key.
โ€ข First Normal Form (1NF)
โ€“
โ€“
โ€“
โ€“
each attribute/column value must be atomic.
(= ์ฆ‰, a single value, not a set of values or another database row).
Figure 3.4์€ skill column์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ’์„ ๊ฐ€์ง€๋ฏ€๋กœ 1NF๊ฐ€ ์•„๋‹ˆ๋‹ค.
(ํ•ด๊ฒฐ2) Figure 3.5; ๊ทธ๋Ÿฌ๋‚˜ redundancy๊ฐ€ ๋งŽ๋‹ค ๏ƒ  Figure 3.6;
23
โ€ข Second Normal Form
โ€“ ์กฐ๊ฑด:
โ€ข all attributes that are not part of the primary key are fully functionally
dependent on the primary key, AND
โ€ข the schema is already in first normal form.
(์˜๋ฏธ) each non-key attribute must be functionally dependent on all parts of the
key. ์ฆ‰, if the primary key is made up of multiple columns, every other attribute
in the table must be dependent on the combination of these columns.
โ€“ ์˜ˆ: Figure 3.5. 1NF์ด์ง€๋งŒ 2NF์€ ์•„๋‹ˆ๋‹ค. ๏ƒง Primary key๊ฐ€ ํŠน์ • row๋ฅผ
uniquely identifyํ•ด์•ผ ํ•˜๋ฏ€๋กœ.
โ€“ ์ด ์˜ˆ์—์„œ๋Š” employeeID and skill์˜ combination์— ์˜ํ•ด์„œ๋งŒ ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ
โ€ข ์ฆ‰, employeeID, skill ๏ƒ  name, job, departmentID
โ€ข ๋˜ํ•œ employeeID ๏ƒ  name, job, departmentID์—์„œ name, job, departmentID๊ฐ€
(fully๊ฐ€ ์•„๋‹Œ) partially functionally dependent on the primary key.
โ€ข Skill์„ ์ด๋Ÿฐ ์‹์œผ๋กœ set upํ•˜๋ฉด (row๋ฅผ uniquely identifyํ•˜๋Š”๋ฐ) employeeID๋งŒ์œผ๋กœ๋Š”
์ถฉ๋ถ„์น˜ ์•Š๋‹ค. (์˜ˆ: the employeeID 7513 identifies three rows. However, the
combination of employeeID and skill will identify a single row ๏ƒจ ๋”ฐ๋ผ์„œ ์ด๋“ค 2๊ฐœ
๋ฅผ ํ•ฉํ•˜์—ฌ primary key๋กœ ์ด์šฉ.)
โ€ข ๏ƒ  ์ด์— ๋”ฐ๋ผ: employee(employeeID, name, job,
, skill)
โ€“ "What are the functional dependencies here?"
โ€ข We have employeeID, skill name, job, departmentID but we also have
employeeID
name, job, departmentID
โ€ข ์ฆ‰, we can determine the name, job, and departmentID from employeeID alone.
โ€“ "How can we put it into second normal form?"
โ€ข
โ€ข
โ€ข
โ€ข
break the table into two tables!!, to wit:
employee(employeeID, name, job,
)
employeeSkills(
, skill)
== Figure 3.6์˜ schema. ์ด๊ฒƒ์€ 1NF์ด๋ฉด์„œ ๋™์‹œ์— 2NF (๏ƒŸ each non-key attribute
24
is now functionally dependent on all parts of the keys.)
โ€ข Third Normal Form
โ€“ Formally, for a schema to be in 3NF,
โ€ข remove all transitive dependencies, AND
โ€ข the schema must already be in second normal form.
(transitive dependency?) Figure 3.3:
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
» employeeDepartment(employeeID, name, job, departmentID, departmentName)
This schema contains the following functional dependencies:
» employeeID๏ƒ  name, job, departmentID, departmentName
» departmentID ๏ƒ departmentName
Primary key is employeeID, and all the attributes are fully functionally dependent on it
However, we can see that we have
» employeeID ๏ƒ  departmentName
» employeeID ๏ƒ  departmentID
and
» departmentID ๏ƒ  departmentName
Note also that the attribute departmentID is not a key. This relationship means that the
functional dependency employeeID departmentName is a transitive dependency. ์—ฌ๊ธฐ์„œ
departmentID๋Š” key๊ฐ€ ์•„๋‹ˆ๋ฉด์„œ๋„ departmentID ๏ƒ  departmentName์˜ dependency๋ฅผ ๊ฐ€์ง€
๋Š”๋ฐ ์ด๋ฅผ transitive dependency๋ผ๊ณ  ํ•œ๋‹ค.
Effectively, it has a middle step (the departmentID departmentName dependency).
To get to third normal form, we need to remove this transitive dependency.
์ฆ‰, decompose this
» employee(employeeID, name, job,
)
» department(departmentID, departmentName)
โ€“ (3NF์˜ ๋‹ค๋ฅธ ํ‘œํ˜„) For every functional dependency in every table, either
โ€ข
The left side of the functional dependency is a superkey (that is, a key that is
not necessarily minimal). or
โ€ข The right side of the functional dependency is part of any key of that table.
25
โ€“ ๋Œ€๋ถ€๋ถ„ functional dependencies will be covered by the first rule!
โ€ข Boyce-Codd Normal Form (BCNF)
โ€“ = a variation on third normal form.
โ€“ Relation์ด BCNF์ด๋ ค๋ฉด ;
โ€ข 3NF +
โ€ข come under the first of the two rules. ์ฆ‰, all the functional
dependencies must have a superkey on the left side.
โ€“ ๋Œ€๋ถ€๋ถ„ ๋ณ„๋‹ค๋ฅธ ์กฐ์น˜๋ฅผ ์ทจํ•˜์ง€ ์•Š์•„๋„ ์ถฉ์กฑ๋œ๋‹ค. ์ด์— ์œ„๋ฐฐ๋˜๋Š”
dependency๊ฐ€ ์žˆ๋‹ค๋ฉด ์•ž ์„œ์™€ ๊ฐ™์ด ๋‹ค์‹œ decompose ์ž‘์—…!
โ€ข Higher Normal Forms
โ€“ practical database design์ด๋ผ๊ธฐ ๋ณด๋‹ค๋Š” ์ฃผ๋กœ ํ•™์ˆ ์  ๋Œ€์ƒ.
โ€“ 3NF (or BCNF) is sufficient to avoid the data redundancy
problems you will encounter.
26
์š”์•ฝ
โ€ข
Concepts
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
Entities are things, and relationships are the links between them.
Relations or tables hold a set of data in tabular form.
Columns belonging to tables describe the attributes that each data item possesses.
Rows in tables hold data items with values for each column in a table.
Keys are used to identify a single row.
Functional dependencies identify which attributes determine the values of other
attributes.
โ€“ Schemas are the blueprints for a database.
โ€ข
Design Principles
โ€“ Minimize redundancy without losing data.
โ€“ Insertion, deletion, and update anomalies are problems that occur when trying to
insert, delete, or update data in a table with a flawed structure.
โ€“ Avoid designs that will lead to large quantities of null values.
โ€ข
Normalization
โ€“
โ€“
โ€“
โ€“
โ€“
Normalization is a formal process for improving database design.
1NF means atomic column or attribute values.
2NF means that all attributes outside the key must depend on the whole key.
3NF means no transitive dependencies.
Boyce-Codd normal form (BCNF) means that all attributes must be functionally
determined by a superkey.
27
4. Database, Table, Index์˜ ์ƒ์„ฑ
28
Creating a database
โ€ข ์ƒ˜ํ”Œ database schema:
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
employee(employeeID, name, job,
)
department(departmentID, name)
employeeSkills(
, skill)
client(clientID, name, address, contactPerson, contactNumber)
assignment(
,
, workdate, hours)
โ€ข SQL (structured query language)
โ€“ DDL (data definition language)
โ€“ DML (data manipulation language)
โ€ข Case Sensitivity
โ€“ SQL keywords
โ€ข are not case sensitive. ๏ƒŸ standard across database systems.
โ€“ Identifiers
โ€ข Database์— ๋”ฐ๋ผ ๋‹ค๋ฅธ๋ฐ MySQL์—์„œ๋Š” ์šด์˜ํ™˜๊ฒฝ(OS)์— ๋”ฐ๋ผ
โ€“ Windows; database/table name์€ not case sensitive
โ€“ Unix-like operating system; case sensitive
โ€“ MacOS X; ํŒŒ์ผ์‹œ์Šคํ…œ ์„ค์ •์— ๋”ฐ๋ผ either case insensitive (HFS+, the
default,) or case sensitive (UFS).
โ€“ ํ˜ผ๋ž€ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  identifier๋ฅผ case sensitive๋กœ ์ทจ๊ธ‰! ๏ƒ  platform๊ฐ„
29
portability ์ฆ์ง„
โ€“ Column ๋ช…, index, aliases๋Š” never case sensitive in MySQL.
Identifiers
โ€ข ๊ฐ์ฒด (object)๋ฅผ uniqueํ•˜๊ฒŒ ์‹๋ณ„ (identify)ํ•˜๋Š” ๊ฒƒ (= name of an
alias, a database, a table, a column, or an index. )
โ€ข ์‚ฌ์šฉ๊ฐ€๋Šฅ ๋ฌธ์ž = ๋ชจ๋“  ๋ฌธ์ž. ๋‹จ,
โ€“ can't contain quote characters, ACSII(0) and ASCII(255).
โ€“ Database ๋ช…์€ Directory๋ช…์— ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  ๋ฌธ์ž๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ โ€˜/, \ ๊ณผ .โ€™
๋Š” ์•ˆ ๋œ๋‹ค.
โ€“ Table ๋ช…์€ filename์— ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฌธ์ž๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ โ€˜. ๊ณผ /โ€™๋Š” ์•ˆ ๋œ๋‹ค.
โ€ข ๊ธธ์ด = 64 ๋ฌธ์ž max (๋‹จ,Alias ๋ช…์€ 255 ๋ฌธ์ž max)
โ€ข ํŠน์ด์ : MySQL์—์„œ๋Š” reserved word๋ฅผ identifier๋กœ ์ด์šฉ๊ฐ€๋Šฅ.
โ€“ (quote๋กœ ๋ฌถ๊ธฐ๋งŒ ํ•˜๋ฉด) reserved word๋ฅผ identifier๋กœ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. (์˜ˆ:
TABLE์ด๋ผ๋Š” ์ด๋ฆ„์˜ table๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ๋‹จ, ๊ถŒ๊ณ ๋˜์ง€๋Š” ์•Š์Œ)
โ€“ (Quote๋กœ ๋ฌถ์ง€ ์•Š์•„๋„ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ๊ฒƒ) (์˜ˆ: DATE, TIMESTAMP๋ฅผ column
๋ช…์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ) == ANSI SQLํ‘œ์ค€์—๋Š” ๋งž์ง€ ์•Š๋Š”๋ฐ ์ผ์ƒ์—์„œ๋Š” ๊ฐ„ํ˜น
์‚ฌ์šฉ
30
Create and Select a Database
โ€ข Create a Database
โ€ข create database employee;
โ€ข show databases;
โ€ข Select a Database
โ€ข use employee;
31
Create Tables
์œคํ˜•๊ธฐ:
โ€ข TEMPORARY; ํ˜„์žฌ์˜ DB session์—์„œ๋งŒ
visibleํ•˜๊ณ  connection์ด ์ข…๋ฃŒ ์‹œ ์‚ญ์ œ๋จ.
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)][table_options] [select_statement]
โ€ข LIKE old_table_name ; create a
new table with the same schema as
old_table_name.
โ€ข Other options:
โ€ข NOT NULL or NULL,
or
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name LIKE
old_table_name;
create_definition:
col_name type [NOT NULL | NULL] [DEFAULT default_value]
[AUTO_INCREMENT]
[PRIMARY KEY] [reference_definition]
or PRIMARY KEY (index_col_name,...)
or KEY [index_name] (index_col_name,...)
or INDEX [index_name] (index_col_name,...)
or UNIQUE [INDEX] [index_name] (index_col_name,...)
or FULLTEXT [INDEX] [index_name] (index_col_name,...)
or [CONSTRAINT symbol] FOREIGN KEY [index_name]
(index_col_name,...)
[reference_definition] or CHECK (expr)
โ€ข DEFAULT ; default value
โ€ข AUTO_INCREMENT ; ๏ƒ  ์ž๋™ index
๋จ. ๋˜ํ•œ Indexes are
automatically created for
columns that are declared as
PRIMARY KEY(๋ณธ sample)
โ€ข REFERENCES ; foreign key
โ€ข PRIMARY KEY = a unique, indexed
column that cannot contain nulls.
โ€ข INDEX = KEY (๋‹จ, unique value์ผ ํ•„์š”
๋Š” ์—†๋‹ค.)
โ€ข UNIQUE ; โ€ฆ (๋‹จ, UNIQUE columns will
also be indexed.)
โ€ข FULLTEXT ; create full-text indexes
on a TEXT, CHAR, or VARCHAR column
type. (MyISAM table only)
โ€ข FOREIGN KEY ; โ€ฆ
โ€ข
32
์œคํ˜•๊ธฐ:
โ€ข Comma-separated list of
column declarations
enclosed in parentheses. (์ฐธ
๊ณ ) column์˜ attribute๋Š”
comma separated์ผ ํ•„์š” ์—†์Œ.
โ€ข White space์™€ ; (์ƒ๋žต)
drop database if exists employee;
create database employee;
use employee;
create table department
(
departmentID int not null auto_increment primary key,
name varchar(30)
) type=InnoDB;
โ€ข varchar์™€ char = ๊ฐ€๋ณ€๊ธธ์ด, ๊ณ 
์ •๊ธธ์ด
โ€ข not null, auto_increment
โ€ข type=InnoDB (Default๋Š”
MyISAM. InnoDB๋Š” foreign
key์™€ transaction์„ ์ง€์›ํ•จ)
โ€ข๋‹จ, MyISAM์ด ๋‹ค์†Œ ๋น ๋ฆ„
โ€ขReferences ์˜๋ฏธ ;
departmentID should be
referenced back to the
departmentID column in the
department table. (foreign
key) โ€“employee table์ด
InnoDB table์ด๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ€๋Šฅ
create table employee
(
employeeID int not null auto_increment primary key,
name varchar(80),
job varchar(30),
departmentID int not null references department(departmentID)
) type=InnoDB;
33
create table employeeSkills
(
employeeID int not null references employee(employeeID),
skill varchar(15) not null,
primary key (employeeID, skill)
) type=InnoDB;
์œคํ˜•๊ธฐ:
โ€ข
primary key
โ€ข
2-column primary key
create table client
(
clientID int not null auto_increment primary key,
name varchar(40),
address varchar(100),
contactPerson varchar(80),
contactNumber char(12)
) type=InnoDB;
34
create table assignment
(
clientID int not null references client(clientID),
employeeID int not null references employee(employeeID),
workdate date not null,
hours float,
primary key (clientID, employeeID, workdate)
) type=InnoDB;
35
show tables;
(output:)
+----------------------------+
| Tables_in_employee
|
+---------------------------+
| assignment
|
| client
|
| department
|
| employee
|
| employeeSkills
|
+--------------------------+
describe department;
(output:)
+----------------+----------------+----------------------+--------+-------+---------+-----------------+
| Field
| Type
| Collation
| Null
| Key
| Default |
Extra
|
+----------------+----------------+-----------------------+-------+-------+----------+----------------+
| departmentID | int(11)
| binary
|
| name
| latin1_swedish_ci
| YES |
| varchar(20)
| PRI
| NULL
| NULL
| auto_increment|
|
______
|
+-----------------+---------------+----------------------+-------+------+-----------+-----------------+
36
โ€ข table options
โ€“ MyISAM, (default)
โ€ข = very fast and supports full-text indexing.
โ€“ ๏ƒŸ previous standard ISAM type.
โ€“ InnoDB
โ€ข = ACID-compliant storage engine that supports transactions, foreign keys,
and row-level locking.
โ€“ BDB (Berkeley DB)
โ€ข a storage engine that supports transactions and page-level locking.
โ€“ HEAP tables
โ€ข are stored completely in memory and are never written to disk, so they are
very fast, but limited in size and are unrecoverable in the event of failure.
โ€“ MERGE tables
โ€ข allow you to combine a set of MyISAM tables with the same structure so that
they can be queried as if they were one table.
โ€ข ์ตœ๋Œ€ ํŒŒ์ผ/ํ…Œ์ด๋ธ” size์˜ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•˜๋Š” ๋ฐฉ๋ฒ•์˜ ํ•˜๋‚˜๋กœ ์ด์šฉ.
37
โ€ข
๊ธฐํƒ€์˜ table options (์ฃผ๋กœ optimization๋ชฉ์ )
; 1 ์ด์™ธ์˜ ๊ฐ’์„ ์ง€์ •
โ€“ AUTO_INCREMENT = #
โ€“ AVG_ROW_LENGTH = #
;โ€ฆ
โ€“ CHECKSUM = 1
; 1 to turn it on. (default: Off) ; MyISAM table๋งŒ ์ ์šฉ
โ€“ COMMENT = "string"
;โ€ฆ
โ€“ MAX_ROWS = #
;โ€ฆ
โ€“ MIN_ROWS = #
;โ€ฆ
โ€“ PACK_KEYS = {0 | 1 | DEFAULT}
โ€ข By default, MySQL packs (compresses) strings in keys (์ฆ‰, CHARs, VARCHARs, and TEXT).
โ€ข 1 = all keys will be packed; 0 = none will be packed.
โ€“ PASSWORD = "string"
; does nothing in the standard version of MySQL.
โ€“ DELAY_KEY_WRITE = {0 | 1} ; key update๋ฅผ table์ด closed๋  ๋•Œ๊นŒ์ง€ delay์‹œํ‚ด.
โ€ข (๋‹จ, MyISAM table์—๋งŒ ์ ์šฉ)
โ€“ ROW_FORMAT= {default | dynamic | fixed | compressed } ; specify the storage
format for rows. (๋‹จ, MyISAM tables์—๋งŒ ์ ์šฉ).
โ€“ RAID_TYPE= {1 | STRIPED | RAID0 } RAID_CHUNKS=# RAID_CHUNKSIZE=#
โ€ข RAID configuration ์„ค์ • (optimization ์šฉ)
โ€“ UNION = (table_name,[table_name...]) ; only for MERGE tables
โ€“ INSERT_METHOD= {NO | FIRST | LAST }
; only for MERGE tables
โ€“ DATA DIRECTORY="absolute path to directory" ; โ€ฆ
โ€“ INDEX DIRECTORY="absolute path to directory" ; index๋ณด๊ด€์žฅ์†Œ ์ง€์ •
โ€ข
(์ฐธ๊ณ ) CREATE TABLE ๋ฌธ์žฅํ˜•์‹์—์„œ ๋งˆ์ง€๋ง‰์— SELECT ๋ฌธ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ
38
โ€“ ๏ƒŸ to fill the new table with the data that is returned by the SELECT statement.
Column and Data Type
โ€ข (3 Basic column types)
โ€“ Numerical types / String or text types/ Date and time types
โ€ข Numerical types
โ€“ ๊ฐœ์š”
โ€“ int (integer=exact type) ๋ฐ float (floating-point = approximate numerical type). -ํ‘œํ˜„ํ˜•์‹์„ ์ง€์ •: salary decimal(10, 2)
โ€“ UNSIGNED and/or ZEROFILL
» UNSIGNED ; column contains only zero or positive numbers.
» ZEROFILL ; number will be displayed with leading zeroes.
โ€ข NUMERIC or DECIMAL (= DEC)
โ€“ store exact floating-point values (์˜ˆ: monetary values.)
โ€“ same range as double-precision floating-point numbers.
โ€ข INTEGER and Variations (INT)
โ€“ = a standard integer, (in 4 bytes ๏ƒ  a range of 232 possible values)
โ€“ several variations on INT: 1/2/3/4/8
» TINYINT (1 byte ๏ƒ  28 possible values). = BIT = BOOL
» SMALLINT (2 bytes ๏ƒ  216 possible values)
» MEDIUMINT is 3 bytes (224 possible values).
» BIGINT is 8 bytes (264 possible values).
โ€ข FLOAT
โ€“ = a single-precision floating-point number.
โ€“ (ํ‘œํ˜„) 1.18x10-38 ~ 3.40x1038 ๋˜๋Š” ๋น„์Šทํ•œ ๋ฒ”์œ„์˜ negative numbers.
โ€ข DOUBLE
โ€“ = a double-precision floating-point number=REAL=DOUBLE PRECISION.
โ€“ (ํ‘œํ˜„) 2.23x10-308 ~ 1.80x10308 ๋˜๋Š” ๋น„์Šทํ•œ ๋ฒ”์œ„์˜ negative numbers.
39
โ€ข String and Text Types
โ€“ CHAR
โ€ข store fixed-length strings.
โ€ข ๊ธธ์ด๋ฅผ ()๋กœ ์ง€์ •. Max=255, Default=1
โ€ข ๊ณ ์ •๊ธธ์ด๋กœ ๋ณด๊ด€๋œ ํ›„ retreive๋  ๋•Œ space๊ฐ€ stripped ๋จ.
โ€“ CHAR takes up more space on disk than variable-length string.
โ€“ Trade-off: faster to retrieve rows (์ฆ‰, CHAR, numeric, or date).
โ€ข Both CHAR and VARCHAR types can be preceded with the keyword NATIONAL,
meaning to restrict the contents to the standard character set. (default์ด๋ฏ€๋กœ
cross-platform compatibility์—์„œ๋งŒ ์˜๋ฏธ๊ฐ€ ์žˆ์Œ)
โ€ข CHAR์™€ VARCHAR ๋ชจ๋‘ ๋’ค์— BINARY๋ฅผ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋‹ค. ; they should be treated as
case sensitive when evaluating string comparisons. (default๋Š” case insensitive).
โ€“ VARCHAR
โ€ข variable-length strings. (0 to 255).
โ€“ TEXT, BLOB, and Variations
โ€ข TEXT types ; storing longer text than in a CHAR or VARCHAR.
โ€ข BLOB ; Binary Large OBject.
โ€“ These types are the same except that BLOBs are for binary data rather than text.
Comparisons on BLOBs are case sensitive, and on TEXTs, they are not.
โ€ข They are both variable in length, but both come in various sizes:
โ€“
โ€“
โ€“
โ€“
TINYTEXT or TINYBLOB ; up to 255 (that's 28-1) characters(bytes).
TEXT or BLOB ; up to 65,535 (216-1) characters or bytes (64KB).
MEDIUMTEXT or MEDUIMBLOB ; up to 16,777,215 (224-1) chars/ bytes (16MB).
LONGTEXT or LONGBLOB ; up to 4,294,967,295 (232-1) characters or bytes (4GB).
โ€“ ENUM
โ€ข a set of possible values. ์˜ˆ: gender enum('m', 'f') ๋‹จ, NULL๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ
์‹ค์ œ๋Š” m, f, NULL, or error.
โ€“ SET
40
โ€ข ENUM๊ณผ ์œ ์‚ฌ. ๋‹จ, rows may contain a set of values from the enumerated set.
โ€ข Date and Time Types
โ€“ DATE
โ€ข in ISO year-month-day order, avoiding trans-Atlantic arguments.
โ€ข Dates are displayed as YYYY-MM-DD.
โ€“ TIME
โ€ข HH:MM:SS.
โ€“ DATETIME
โ€ข = a combination of the previous types.
โ€ข YYYY-MM-DD HH:MM:SS.
โ€“ TIMESTAMP
โ€ข If you do not set this column in a particular row, or set it to NULL, it
will store the time that row was inserted or last changed.
โ€ข When you retrieve a timestamp, it will be displayed in the DATETIME
format. (version 4.0 to 4.1๊ณผ๋Š” ๋‹ฌ๋ผ์ง. โ€ฆ)
โ€“ YEAR
โ€ข you can declare it as YEAR(2) or YEAR(4) to specify the number of
digits. YEAR(4) is the default.
โ€ข YEAR(2) represents the range 1970 to 2069.
41
Creating Indexes
โ€ข ์ผ๋ฐ˜๋ก 
โ€“ PRIMARY KEY, KEY, UNIQUE, or INDEX ๋กœ ์„ ์–ธ๋œ column์€
will be indexed.
โ€ข CREATE INDEX
โ€“ CREATE INDEX statement is mapped to an ALTER TABLE
statement before being executed.
โ€“ (์˜ˆ:) create index name on employee(name);
โ€“ create index statement์—๋Š” option์ด ๋งŽ์ง€ ์•Š๋‹ค.
โ€ข CREATE UNIQUE index ; enforce a uniqueness constraint.
โ€ข CREATE FULLTEXT ; create a full-text index on a MyISAM table.
โ€ข Limit indexes on char and varchar types to index just the first
few characters in each field.
โ€“ ์˜ˆ: create index part_name on employee(name(5));
โ€“ ์ด์œ : indexes on text types are not as efficient as indexes on
numeric types, and just indexing the first few characters improves
performance.
42
Databases, Tables, Index์˜ ์‚ญ์ œ
โ€ข (๋ช…๋ น์–ด) drop database employee;
โ€“ optional IF EXISTS clause before the database name
โ€ข DROP TABLE statement:
โ€“ DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name,...]
โ€ข TEMPORARY ; for dropping temporary tables.
โ€ข ๊ธฐํƒ€ ์ƒ๋žต
โ€ข DROP INDEX statement
โ€“ drop index part_name on employee;
43
Altering Existing Table Structures
โ€ข ALTER TABLE
์œคํ˜•๊ธฐ: ํŠน์ด์‚ฌํ•ญ๋งŒ ๊ฒ€ํ† :
โ€ข CHANGE / MODIFY (๊ณตํ†ต); column
definition or table์—์„œ์˜ position ๋ณ€
ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]
๊ฒฝ.
โ€ข DROP COLUMN ; deletes a column
alter_spec:
from the table (๋น„๊ต) DROP PRIMARY
ADD [COLUMN] create_definition [FIRST | AFTER col_name ]
KEY and DROP INDEX delete just the
or ADD [COLUMN] (create_definition, create_definition,...)
associated index for that column.
or ADD INDEX [index_name] (index_col_name,...)
โ€ข DISABLE KEYS ; stop updating
indexes for a MyISAM table only.
or ADD PRIMARY KEY (index_col_name,...)
ENABLE KEYS turns index updating
or ADD UNIQUE [index_name] (index_col_name,...)
back on.
or ADD FULLTEXT [index_name] (index_col_name,...)
โ€ข RENAME ; change name of a table.
or
ADD [CONSTRAINT symbol] FOREIGN KEY [index_name]
โ€ข ORDER BY ; put the rows in the
(index_col_name,...)
newly altered table in a particular
[reference_definition]
order (This order will not be
or ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
maintained as the data in the table
or CHANGE [COLUMN] old_col_name create_definition
changes over time.)
[FIRST | AFTER column_name]
โ€ข table_options ; lets you specify
the same table options as at the
or MODIFY [COLUMN] create_definition [FIRST | AFTER col_name]
end of the CREATE TABLE
or DROP [COLUMN] col_name
statement.
or DROP PRIMARY KEY
or DROP INDEX index_name
or DISABLE KEYS
or ENABLE KEYS
44
or RENAME [TO] new_tbl_name
or ORDER BY col_name or table_options
5. Inserting, Deleting, and
Updating Data
45
Listing 5.1 employee_data.sql
use employee;
delete from department;
insert into department values
(42, 'Finance'),
(128, 'Research and Development'),
(NULL, 'Human Resources'),
(NULL, 'Marketing');
delete from employee;
insert into employee values
(7513,'Nora Edwards','Programmer',128),
(9842, 'Ben Smith', 'DBA', 42),
(6651, 'Ajay Patel', 'Programmer', 128),
(9006, 'Candy Burnett', 'Systems Administrator', 128);
46
delete from employeeSkills;
insert into employeeSkills values
(7513, 'C'),
(7513, 'Perl'),
(7513, 'Java'),
(9842, 'DB2'),
(6651, 'VB'),
(6651, 'Java'),
(9006, 'NT'),
(9006, 'Linux');
delete from client;
insert into client values
(NULL, 'Telco Inc', '1 Collins St Melbourne', 'Fred Smith',
'95551234'),
(NULL, 'The Bank', '100 Bourke St Melbourne', 'Jan Tristan',
'95559876');
delete from assignment;
insert into assignment values
(1, 7513, '2003-01-20', 8.5);
47
select * from department;
+------------------+---------------------------+
| departmentID |
name
|
+------------------+---------------------------+
|
42
| Finance
|
|
128
|Research and Develop
|
|
129
| Human Resources
|
|
130
| Marketing
|
+-----------------+-----------------------------+
4 rows in set (0.01 sec)
48
์œคํ˜•๊ธฐ:
โ€ข LOW PRIORITY or DELAYED.
(general form of the INSERT statement)
INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name [(col_name,...)]
VALUES ((expression | DEFAULT),...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expression, ... ]
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
or INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
[INTO] tbl_name
SET col_name=(expression | DEFAULT), ...
[ ON DUPLICATE KEY UPDATE
col_name=expression, ... ]
; (๊ณตํ†ต) insertion will be delayed until no client is
trying to read from the table.
; (์ฐจ์ด์ ) LOW PRIORITY will block the inserting
client and DELAYED will not. ์ฆ‰,
โ€ขLOW PRIORITY insert; ์ž ์‹œ ๊ธฐ๋‹ค๋ฆฐ ํ›„ query์ˆ˜
ํ–‰
โ€ขDELAYED; you will be told OK and can
continue running queries, but you need to
remember that the insert will not be
performed until the table is not in use.)
โ€ข IGNORE ; chiefly useful when inserting multiple
rows. ๋ณดํ†ต ์‹ ๊ทœ ์ž…๋ ฅ row๊ฐ€ ๊ธฐ์กด์˜ row์˜ PRIMARY
KEY or UNIQUE value์™€ clash๋˜๋ฉด errorํ‘œ์‹œ ํ›„ insert
์ž์ฒด๊ฐ€ abort๋˜์ง€๋งŒ IGNORE๋กœ ์ง€์ •ํ•˜๋ฉด, error will be
ignored and the insert will continue and will attempt
to insert the next row.
โ€ข DEFAULT ; column์˜ default value ์ง€์ •.
โ€ข ON DUPLICATE KEY UPDATE ; (๋’ท์žฅ)
49
โ€ขON DUPLICATE KEY UPDATE
โ€“ Primary key ๋˜๋Š” unique value๊ฐ€ clash๋  ๋•Œ ์ ์ ˆํ•œ ์ฒ˜๋ฆฌ๋ฐฉ
๋ฒ• ์ œ์‹œ. ์ฆ‰, change the primary key or unique value in
the row already in the table so that it no longer clashes
with the new row.
โ€“ (์˜ˆ:)
create table warning
(
employeeID int primary key not null
references employee(employeeID),
count int default 1
) type =InnoDB;
insert into warning (employeeID)
values (6651)
on duplicate key update
count=count+1;
์œคํ˜•๊ธฐ:
(๋‹ค์Œ ์ƒํ™ฉ์— ์œ ์šฉ) unique event ๋ฐœ์ƒ ์‹œ ์ด๋ฅผ ๊ธฐ๋ก
(record)ํ•  ๋ฟ ์•„๋‹ˆ๋ผ ์–ด๋–ค action์„ ์ทจํ•˜๊ณ ์ž ํ•  ๋•Œ
(์˜ˆ1) increment a counter when non-unique
events occur.
(์˜ˆ2) ๊ฐ์ข… logging (์œ„์˜ employee DB์—์„œ we will
record employees who have been given a
warning in the table warning.)
์–ด๋–ค ์‚ฌ๋žŒ์˜ warning์„ ๊ธฐ๋กํ•  ๋•Œ count์˜ default
๊ฐ’์ด 1์ผ ๋•Œ, ์ถ”๊ฐ€์˜ (subsequent) insert ๋ฐœ์ƒ ์‹œ
(๋™์ผ employeeID์— ๋Œ€ํ•ด) ON DUPLICATE KEY UPDATE
clause ์— ์˜ํ•ด counter ๊ฐ’์„ ์ฆ๊ฐ€.
50
Using REPLACE
(general form of REPLACE)
REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name [(col_name,...)]
VALUES (expression,...),(...),...
or REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name [(col_name,...)]
SELECT ...
or REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name
SET col_name=expression, col_name=expression,...
51
Using DELETE
โ€ข delete from department;
โ€“ ๏ƒ delete all the rows from the table.
โ€“ ์‹ค์ˆ˜์— ๋Œ€๋น„:โ€“-safe-updates ๋˜๋Š” โ€“-i-am-a-dummy option
โ€ข delete from department where name='Asset Management';
์œคํ˜•๊ธฐ:
delete employee, employeeSkills
DELETE [LOW_PRIORITY] [QUICK] FROM table_name
[WHERE where_definition]
[ORDER BY ...]
[LIMIT rows]
or
DELETE [LOW_PRIORITY] [QUICK] table_name[.*]
[, table_name[.*] ...]
FROM table-references
[WHERE where_definition]
or DELETE [LOW_PRIORITY] [QUICK]
FROM table_name[.*] [, table_name[.*] ...]
USING table-references
[WHERE where_definition]
from employee, employeeSkills, department
where employee.employeeID = employeeSkills.employeeID
and employee.departmentID = department.departmentID
and department.name='Finance';
delete from employee, employeeSkills
using employee, employeeSkills, department
where employee.employeeID = employeeSkills.employeeID
and employee.departmentID = department.departmentID
and department.name='Finance';
(๋‹ค๋ฅธ optional clauses)
· * LOW_PRIORITY clause; (์ƒ๋žต)
· * QUICK ; DELETE ์‹œ index์— ๋Œ€ํ•œ housekeeping ์ผ๋ถ€์ž‘์—… ์ƒ๋žต
๏ƒ  speed up
· ; ORDER BY ; row ์‚ญ์ œ์‹œ์˜ ์ˆœ์„œ ์ง€์ • - LIMIT ๋ฌธ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜
๋ฉด ์œ ์šฉ โ€”(์˜ˆ) delete the oldest n rows from a table.
52
; LIMIT ; DELETE ๋กœ ์‚ญ์ œ๋  ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ row ์ˆซ์ž๋ฅผ ์„ค์ •
Using TRUNCATE
โ€ข delete all the rows from a table.
โ€ข ์˜ˆ: TRUNCATE TABLE employee;
โ€ข DELETE ๋ฌธ๋ณด๋‹ค ๋น ๋ฅด๋‹ค. (๏ƒŸ works by dropping the
table and re-creating it empty. )
โ€ข ๋‹จ, TRUNCATE is not transaction safe.
53
Using UPDATE
(general form of the UPDATE statement)
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name
SET col_name1=expr1 [, col_name2=expr2 ...]
[WHERE where_definition]
[ORDER BY ...]
[LIMIT rows]
or
UPDATE [LOW_PRIORITY] [IGNORE] tbl_name [, tbl_name ...]
SET col_name1=expr1 [, col_name2=expr2 ...]
[WHERE where_definition]
โ€ข ํŠน์ด์‚ฌํ•ญ ์—†์Œ.
54
Uploading Data with LOAD DATA INFILE
(general form of the LOAD DATA INFILE statement)
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL]
INFILE 'fileName.txtโ€˜
[REPLACE | IGNORE]
INTO TABLE tbl_name
[FIELDS
[TERMINATED BY '\t']
[[OPTIONALLY] ENCLOSED BY '']
[ESCAPED BY '\\' ]
]
[LINES TERMINATED BY '\n']
[IGNORE number LINES]
[(col_name,...)]
โ€ข
โ€ข
bulk insert data from a text file into a single table
(INSERT ๋Œ€์‹ )
Listing 5.2 department_infile.txt
42
Finance
128 Research and Development
NULL Human Resources
NULL Marketing
load data local infile 'department_infile.txtโ€˜
into table department;
โ€ข
โ€ข
์œคํ˜•๊ธฐ:
optional clauses:
· * LOW PRIORITY clause ; (์ƒ๋žต)
* CONCURRENT allows other clients to read
from the table while the bulk insert is going on.
· * LOCAL; means the data file is on client
machine. (LOCAL์ด ์—†์œผ๋ฉด MySQL์€ ์„œ๋ฒ„์—์„œ
infile ์„ ์ฐพ์Œ)
· *
๋ฐ์ดํ„ฐ insert๊ณผ์ •์—์„œ clash ๋ฐœ์ƒ ์‹œ 2๊ฐ€์ง€ ๋Œ€์ฒ˜:
- REPLACE replace old row with new row,
- IGNORE tells MySQL to keep old row.
· * FIELDS and LINES ; infile์— ์ˆ˜๋ก๋œ ๋ฐ์ดํ„ฐ๊ฐ€
layout๋˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์ •. ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” default๊ฐ’ ์ด
์šฉ.โ€”each row on a new line, column values
separated by tabs. We can also enclose column
values in quotes and use the backslash
character to escape any special characters (like
single quotes) that might confuse MySQL.
·
* IGNORE number LINES ; ignore the first
number lines in the infile.
·
* ๋งˆ์ง€๋ง‰ ์ค„์˜ col_name; allows you to specify
that you only want to read data into some of
the table's columns.
๋‹ค๋ฅธ DB format, spreadsheet, CSV
file ๋กœ๋ถ€ํ„ฐ data convertํ•˜๋Š” ๋ฐ์— ์œ ์šฉ.
(์ฃผ์˜) FILE privilege๊ฐ€ ํ•„์š”ํ•จ. ๏ƒŸ security reasons (์˜ˆ) to stop
from loading in /etc/passwd
55
โ€ข Listing 5.3 new_programmers.csv
Name,Job,DepartmentID
Julia Lenin,Programmer,128
Douglas Smith,Programmer,128
Tim O'Leary,Programmer,128
โ€ข Load this data into employee table with:
load data infile 'e:\\new_programmers.csvโ€˜
into table employee
fields terminated by ',โ€˜
lines terminated by '\nโ€˜
ignore 2 lines
(name, job, departmentID);
โ€ข (์ฃผ์š”์‚ฌํ•ญ)
โ€“ Windows/DOS-style path์—์„œ์˜ backslash์ฒ˜๋ฆฌ
๏ƒ 'e:\\new_programmers.csv'.
โ€“ CSV file are terminated by commas
โ€“ first two lines as a header should be ignored.
56
6. Querying MySQL
57
Overview of SELECT
โ€ข
General form:
SELECT columns
FROM tables
[WHERE conditions]
[GROUP BY group
[HAVING group_conditions]]
[ORDER BY sort_columns]
[LIMIT limits];
โ€ข
โ€ขํŠน์ • column์˜ ์„ ํƒ
select name, employeeID from
select * from department; ๏ƒจ
employee; ๏ƒจ
+--------------------+---------------------------------+
+-----------+----------+
| departmentID
|
name
|
| name
| employeeID |
+--------------------+---------------------------------+
+-----------+----------+
|
42
| Finance
|
| Ajay Patel
|
6651 |
|
128
| Research and Development
|
| Nora Edwards |
7513 |
|
129
| Human Resources
|
| Candy Burnett |
9006 |
|
130
| Marketing
|
| Ben Smith
|
9842 |
+--------------------+---------------------------------+
+------------+---------+
4 rows in set (0.00 sec)
4 rows in set (0.00 sec)
Simple Queries
58
โ€ข Specifying Absolute Databases and Tables
select employee.name from employee; ๏ƒจ
+-----------------+
| name
|
+-----------------+
| Ajay Patel
|
| Nora Edwards |
| Candy Burnett |
| Ben Smith
|
+------------------+
4 rows in set (0.41 sec)
โ€“ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ,
โ€ข select name from employee.employee; ๏ƒจ
โ€ข (์œ„์™€ ๋™์ผํ•œ ๊ฒฐ๊ณผ)
โ€“ ๊ฐ€๊ธ‰์  database.table.column syntax:
โ€ข select employee.employee.name from employee;
59
โ€ข Aliases
โ€“ rename columns or expressions in a SELECT statement
select name as employeeName
from employee; ๏ƒจ
+----------------------+
| employeeName
|
/* ์—ฌ๊ธฐ์„œ employeeName์ด alias์ด๋‹ค */
+----------------------+
| Ajay Patel
|
| Nora Edwards
|
| Candy Burnett
|
| Ben Smith
|
+----------------------+
4 rows in set (0.01 sec)
โ€“ ๋‹ค๋ฅธ ์˜ˆ:
โ€ข select e.namefrom employee as e; ๏ƒจ Alias๋ฅผ ์“ฐ๋˜ ๋ง๋˜ ๊ฒฐ๊ณผ๋Š” ๊ฐ™๋‹ค.
โ€“ ์•ž์˜ ์˜ˆ์—์„œ keyword AS๋Š” optional. ์ฆ‰,
select name employeeName from employee;
select e.name from employee e;
AND
60
ํŠน์ • Row์„ ํƒ์„ ์œ„ํ•œ WHERE Clause ์‚ฌ์šฉ
โ€ข ๊ฐ„๋‹จํ•œ ์˜ˆ:
select employeeID, name ๏ƒจ +----------------+-----------------+
from employee
| employeeID
| name
|
where job='Programmer';
+-----------------+----------------+
|
6651
| Ajay Patel
|
|
7513
| Nora Edwards |
+-----------------+----------------+
2 rows in set (0.42 sec)
โ€“ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ฃผ์š” operators:
โ€ข =, <>, >, <, >=, <= (๋น„๊ต ์‹œ ์ˆ˜์‹ ์ ์šฉ ๊ฐ€๋Šฅ)
(์˜ˆ: somevalue > someothervalue*10)
โ€ข IS NULL , IS NOT NULL (์ด๊ฒƒ์„ somevalue=NULL ์—ฌ๋ถ€ test์— ์‚ฌ์šฉ ๋ถˆ๊ฐ€.)
โ€ข ํ‘œ์ค€ Boolean operators (AND, OR, NOT) ์‚ฌ์šฉ๊ฐ€๋Šฅ. ๋‹จ, ๋น„๊ต operator๋ณด๋‹ค๋Š”
ํ›„ ์ˆœ์œ„ (์˜ˆ: salary > 30000 AND salary < 50000)
โ€“ ๋งŽ์ด ์“ฐ์ด๋Š” ํ•จ์ˆ˜: count() ; query์— ๋”ฐ๋ฅธ row ์ˆซ์ž count
(์˜ˆ) select count(*) from employee; ๏ƒจ โ€œhow many rows in โ€ฆโ€
โ€“ ๋˜ํ•œ precedence ์กฐ์ ˆ by grouping expressions with parentheses. ์˜ˆ:
select * from assignment
where employeeID=6651 and hours > 8;
โ€“ (์ฃผ์˜) WHERE ์—๋Š” column aliases๋ฅผ ์‚ฌ์šฉ๋ถˆ๊ฐ€(=ANSI SQL ํ•œ๊ณ„)
โ€“ ์ด์œ : alias ์ฒ˜๋ฆฌ๋œ column ๊ฐ’์€ WHERE ์กฐ๊ฑด์ด ๊ฒ€์‚ฌ๋˜๋Š” ์‹œ์ ์—๋Š” ์•Œ ์ˆ˜ ์—†๋Š” ์ƒํƒœ
61
Removing Duplicates with DISTINCT
โ€ข ์˜ˆ:
select count(job) from employee;
+--------------+
| count(job) |
+--------------+
|
4
|
+--------------+
1 row in set (0.01 sec)
โ€ข Misleading! ์ •ํ™•ํ•œ ๋ฐฉ๋ฒ•์€:
select count(distinct job) from employee;
+------------------------+
| count(distinct job)
|
+------------------------+
|
3
|
+-----------------------+
1 row in set (0.05 sec)
โ€ข ์ฆ‰, how many different values are in the job column
62
Using the GROUP BY Clause
select count(*), job
from employee
group by job; ๏ƒจ
+------------+-----------------------------+
| count(*) | job
|
+------------+-----------------------------+
|
1
| DBA
|
|
2
| Programmer
|
|
1
| Systems Administrator |
+------------+-------------------------------+
3 rows in set (0.04 sec)
โ€ข MySQL and ANSI SQL ์—์„œ์˜ 2๊ฐ€์ง€ ์ฐจ์ด์ :
โ€“ ANSI SQL; you must group by all the columns you have listed in the
initial SELECT clause.
โ€“ MySQL; you can have additional fields in the SELECT clause that are
not in the GROUP BY clause. ๋˜ํ•œ group order์˜ sort๋„ ๊ฐ€๋Šฅ. ์˜ˆ:
select count(*), job
from employee
group by job desc; ๏ƒจ
+----------+-----------------------------+
| count(*) | job
|
+----------+-----------------------------+
|
1 | Systems Administrator
|
|
2 | Programmer
|
|
1 | DBA
|
+----------+-----------------------------+
3 rows in set (0.04 sec)
63
โ€ข
Selecting Particular Groups with HAVING
โ€“ GROUP BY with a HAVING clause ; SELECT with a WHERE clause์™€ ์œ ์‚ฌ. ์˜ˆ:
select count(*), job
from employee
group by job
having count(*)=1; ๏ƒจ
+----------+--------------------------------+
| count(*) | job
|
+----------+--------------------------------+
|
1 | DBA
|
|
1 | Systems Administrator |
+----------+--------------------------------+
2 rows in set (0.05 sec)
โ€“ WHERE์™€ HAVING
โ€ข WHERE ; ๊ฐœ๋ณ„ row์— ๋Œ€ํ•œ ์กฐ๊ฑด test๋กœ์„œ ์ผ์ƒ์ ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉ๋จ.
โ€ข HAVING; whole group์— ๋Œ€ํ•œ ์กฐ๊ฑด ํ…Œ์ŠคํŠธ.
โ€ข
Sorting Search Results with ORDER BY
select *
from employee
order by job asc, name desc; ๏ƒจ
+-----------------+-------------------+-------------------------------+-------------------+
| employeeID
| name
| job
| departmentID |
+-----------------+-------------------+-------------------------------+-------------------+
|
9842
| Ben Smith
| DBA
|
42
|
โ€ฆ
|
9006
| Candy Burnett
| Systems Administrator
|
128
|
+-----------------+--------------------+------------------------------+-------------------+
4 rows in set (0.02 sec)
64
โ€“ Default๋Š” ASC. ๋‹จ, ORDER BY ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์‚ฐ์ถœ๋ฌผ์˜ ์ˆœ์„œ๋Š” ์žฅ๋‹ดํ•  ์ˆ˜ ์—†๋‹ค.
Limiting Search Results with LIMIT
โ€“ ์˜ˆ:
select *
from employeeSkills
limit 5; /*๏ƒจ only the first five rows that match the selection criteria */
+-----------------+-------+
| employeeID
| skill |
+-----------------+-------+
|
6651
| Java |
|
6651
| VB
|
|
7513
|C
|
|
7513
| Java |
|
7513
| Perl |
+-----------------+-------+
5 rows in set (0.44 sec)
โ€“ ๋‹ค๋ฅธ ์˜ˆ (to retrieve rows 6 through 8 from the preceding query):
select *
from employeeSkills
limit 5, 3; /*๏ƒจ ์•ž ํŒŒ๋ผ๋ฏธํ„ฐ=offset (start point), ๋’ค ํŒŒ๋ผ๋ฏธํ„ฐ = ์›ํ•˜๋Š” max no of rows*/
โ€“ Row numbering starts from zero when specifying offsets (์•ž์˜ ์˜ˆ์—์„œ 6th row
๋Š” offset 5๋กœ ํ‘œํ˜„). (์•ž์˜ ์˜ˆ์—์„œ๋Š” rows 0 to 4, ๋’ค์˜ ์˜ˆ์—์„œ๋Š” rows 5 to 7.)
โ€“ second parameter๊ฐ€ -1 ์ด๋ฉด offset ๋ถ€ํ„ฐ table์˜ ๋๊นŒ์ง€ ์ƒ์„ฑ๋จ.
โ€“ LIMIT ์™€ ORDER BY๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์œ ์šฉ. (๋‹จ, ORDER BY ์—†์ด ์‚ฌ์šฉํ•˜๋ฉด ์•„๋ฌด๋Ÿฐ
๋…ผ๋ฆฌ์  ์ˆœ์„œ ์—†์ด record๋ฅผ retrieveํ•จ.)
65
โ€“ ํŠนํžˆ Web or GUI applications ๊ฐœ๋ฐœ์— ์œ ์šฉ. ๏ƒŸ easy mechanism for paging
7. Advanced Queries
โ€ข ์—ฌ๋Ÿฌ table์— ๋Œ€ํ•œ join
โ€“ Natural, inner, and cross joins
โ€“ Straight joins
โ€“ Left and right joins
โ€ข Subquery์˜ ์ž‘์„ฑ๊ณผ ์ด์šฉ
โ€ข SELECT๋ฌธ์—์„œ์˜ options
66
Using Joins to Run Queries over Multiple Tables
โ€ข
โ€ข
(๊ฐœ์š”) RDBMS์˜ ํŠน์ง•=relationships= table๋“ค ์‚ฌ์ด์˜ link๋กœ๋ถ€ํ„ฐ ์ •๋ณด์„ ํƒ=join
Joining Two Tables
โ€“ ์˜ˆ (employee name๊ณผ ๊ทธ๋“ค์ด ๊ทผ๋ฌดํ•˜๋Š” department name):
select employee.name, department.name
from employee, department
where employee.departmentID = department.departmentID; ๏ƒจ
+---------------------+-----------------------------------+
| name
| name
|
+---------------------+-----------------------------------+
| Ben Smith
| Finance
|
โ€ฆ
+--------------------+-------------------------------------+
4 rows in set (0.42 sec)
โ€“ WHERE ์—†์ด ์‚ฌ์šฉํ•˜๋ฉด โ€œall possible combinations of โ€ฆ = Cartesian product of the two tables.
โ€“ ์ด ์˜ˆ์—์„œ๋Š” employee.departmentID = department.departmentID๊ฐ€ join condition (= the
link between the tables based on the foreign keys in our original schema).
โ€“ ๋˜ํ•œ readability๋ฅผ ์œ„ํ•ด์„œ๋Š” aliases์‚ฌ์šฉ.
select employee.name as employeeName, department.name as departmentName
from employee, department
where employee.departmentID = department.departmentID; ๏ƒจ
+----------------------+--------------------------+
| employeeName
| departmentName
|
+----------------------+--------------------------+
| Ben Smith
| Finance
|
โ€ฆ
67
+---------------------+---------------------------+
4 rows in set (0.55 sec)
โ€ข
Joining Multiple Tables
โ€“ ์˜ˆ: Telco Inc.๋ผ๋Š” ๊ณ ๊ฐ์— ํ• ๋‹น๋œ department's employees๋ฅผ ์ฐพ๊ณ ์ž ํ•จ.
โ€“ ํ•ด๋ฒ•: client name > clientID > assignments in the assignment table >
employeeIDs from the assignment table > ids of the departments they work for
from employee table > department name from department table
select department.name
from client, assignment, employee, department
where client.name='Telco Incโ€˜
and client.clientID = assignment.clientID
and assignment.employeeID = employee.employeeID
and employee.departmentID = department.departmentID; ๏ƒจ
+------------------------------------+
| name
|
+------------------------------------+
| Research and Development
|
+------------------------------------+
1 row in set (0.00 sec)
โ€“ ์ด ์˜ˆ์—์„œ โ€ฆ (guideline) If you are joining n tables, in most cases, you will have a
link between each pair of tables, and therefore have n-1 join conditions. (Fig 7.1)
68
โ€ข Self Joins - Joining a Table to Itself
โ€“ ์ด๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
โ€ข Find Nora Edwards์™€ ๊ฐ™์€ ๋ถ€์„œ(department)์—์„œ ๊ทผ๋ฌดํ•˜๋Š” ์‚ฌ๋žŒ.โ€
โ€ข (ํ•ด๋ฒ•) find the departmentID Nora works for from the employee table >
employee table์—์„œ ๊ทธ deparment์— ๊ทผ๋ฌดํ•˜๋Š” employee๋ฅผ ์ฐพ์•„ ๋ƒ„.
select e2.name
from employee e1, employee e2
where e1.name = 'Nora Edwardsโ€˜
and e1.departmentID = e2.departmentID;
โ€ข ์ด ์˜ˆ์—์„œ employee table์— ๋Œ€ํ•ด 2๊ฐœ์˜ aliases ์„ ์–ธ ๏ƒ  pretend we have two
separate tables, e1 and e2, which just happen to contain the same data.
๊ทธ๋Ÿฐ ํ›„ simply join them as we would any two other tables.
+-------------------+
| name
|
+-------------------+
| Ajay Patel
|
| Nora Edwards |
| Candy Burnett |
+-------------------+
3 rows in set (0.00 sec)
โ€“ ์—ฌ๊ธฐ์„œ Nora๋ฅผ ๋นผ๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •
select e2.name
from employee e1, employee e2
where e1.name = 'Nora Edwardsโ€˜
and e1.departmentID = e2.departmentID
and e2.name != 'Nora Edwards';
69
Join Type์˜ ์ข…๋ฅ˜
โ€ข Basic Join
โ€“ ์•ž์—์„œ์˜ Cartesian product = full join = cross join ; ๏ƒ 
โ€ข complete set of combinations.(๏ƒŸ FROM ๊ณผ comma๋กœ table ๋‚˜์—ด)
โ€“ Join์— ์กฐ๊ฑด๋ฌธ์„ ๋ถ™์—ฌ์„œ ๊ฒฐ๊ณผ๋ฅผ ํ•œ์ •์‹œํ‚ค๋Š” ๊ฒƒ = equijoin
โ€ข (์˜ˆ: employee.departmentID = department.departmentID)
โ€“ Consider our original query:
select employee.name, department.name
from employee, department
where employee.departmentID = department.departmentID;
โ€“ Optionally, comma๋Œ€์‹  keyword JOIN์„ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
select employee.name, department.name
from employee join department
where employee.departmentID = department.departmentID;
โ€“ JOIN๋Œ€์‹  CROSS JOIN or INNER JOIN ์‚ฌ์šฉ๊ฐ€๋Šฅ.
โ€ข ์ด๋“ค join ์ˆ˜ํ–‰ ์‹œ MySQL looks at the tables we are joining and tries
to work out the most efficient way to join them together, rather
than necessarily joining the tables in the order we have listed. ๊ฐ„ํ˜น
์ด๋Ÿฌํ•œ query optimization์ด ์˜๋„๋Œ€๋กœ ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋„ ์žˆ๋‹ค.
โ€ข If you want to override the optimizer and force to join tables70in the
order in which you list them, replace JOIN with STRAIGHT JOIN.
โ€ข Understanding LEFT and RIGHT Joins
โ€“ ์•ž์„œ equijoin์˜ ๊ฒฝ์šฐ JOIN, CROSS JOIN, INNER JOIN, or STRAIGHT JOIN์„ ์‚ฌ์šฉ.
โ€“ ์˜ˆ: <<ํ•œ table์—๋Š” ์žˆ๋Š”๋ฐ ๋‹ค๋ฅธ table์—๋Š” ํ•ด๋‹น record๊ฐ€ ์—†๋Š” row๋ฅผ ์ฐพ์Œ>>
โ€“ find employees who have not yet worked on any outside assignments!
select employee.name
from employee left join assignment
on employee.employeeID = assignment.employeeID
where clientID is null; ๏ƒจ
+-------------------+
| name
|
+-------------------+
| Ajay Patel
|
| Candy Burnett |
| Ben Smith
|
+-------------------+
3 rows in set (0.49 sec)
โ€“ left join
โ€ข take the left-hand table in the join (์—ฌ๊ธฐ์„œ๋Š” employee) and try to match it to rows in
the right-hand table. (Join์—์„œ์˜ ์™ผ์ชฝ table์„ ์˜ค๋ฅธ ์ชฝ table์— match์‹œํ‚ด. )
โ€ข ๏ƒ  Right table์— matching๋˜๋Š” row๊ฐ€ ์—†๋Š” left table์˜ ๊ฐ๊ฐ์˜ row์— ๋Œ€ํ•ด์„œ๋Š” LEFT JOIN
substitutes a row of NULL values. (๋”ฐ๋ผ์„œ NULL key value ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ฉด right table์—
matching row๊ฐ€ ์—†๋Š” left table์˜ row๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.) ์ฆ‰, โ€œdummy rowโ€๋ฅผ ์ƒ์„ฑ ์‹œํ‚ด.
(The clientID is a key field, so this should never occur in the assignment table.)
โ€ข ์•ž์˜ ์˜ˆ์—์„œ: When an employee has no matching row in the assignment table, the left
join will make up a "dummy row" consisting of all NULLs. ๏ƒ  find these dummy rows by
looking for employees who have worked on an assignment for which clientID is NULL.
71
โ€“ ์ด ์˜ˆ์—์„œ RIGHT JOIN์„ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. (uses the right table as a base and fills
any missing rows from the left table with NULLs.)
Writing Subqueries
โ€ข (๊ฐœ์š”)
โ€“ Subquery = a query within a query = nested queries = subselect
โ€“ ์ƒˆ ๊ธฐ๋Šฅ์€ ์—†์ง€๋งŒ (๋ณต์žกํ•œ set of joins๋Œ€์‹  ์‚ฌ์šฉ๋˜์–ด์„œ) readability ๊ฐœ์„ .
โ€ข Using Derived Table Subqueries
โ€“ list a query in the FROM clause of another query. ๏ƒ  create a
temporary table and add it to the query. ์˜ˆ:
select employeeID, name from employee where job='Programmer';
โ€“ ์ด๊ฒƒ์„ ๋‹ค์Œ ๊ฒฝ์šฐ์— ํ™œ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค.
select programmer.name
from (select employeeID, name from employee where job='Programmer')
as programmer,
assignment
where programmer.employeeID = assignment.employeeID; ๏ƒจ
+-------------------+
| name
|
+-------------------+
| Nora Edwards
|
+-------------------+
1 row in set (0.01 sec)
72
โ€ข Using Single-Value Subqueries
select max(hours) from assignment;
โ€“ ์ด๊ฒƒ์„ ๋‹ค์Œ ๊ฒฝ์šฐ์— ํ™œ์šฉ
select e.employeeID, e.name
from employee e, assignment a
where e.employeeID = a.employeeID
and a.hours = (select max(hours) from assignment); ๏ƒจ
+-----------------+------------------+
| employeeID
| name
|
+-----------------+------------------+
|
7513
| Nora Edwards |
+-----------------+------------------+
1 row in set (0.42 sec)
โ€ข Subqueries๊ฐ€ single value๊ฐ€ ์•„๋‹Œ row๋ฅผ ์‚ฐ์ถœํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
73
โ€ข Boolean Expression Subqueries
โ€“ (์šฉ๋„) check our query against some special functions that
return a Boolean expression. (์˜ˆ:IN, EXISTS, (grouped
together) ALL, ANY, and SOME.) ์˜ˆ:
select name
from employee
where employeeID not in
(select employeeID
from assignment);
โ€“ ์•ž์„œ์˜ LEFT JOINํ™œ์šฉ๊ณผ ๊ฐ™์€ ํšจ๊ณผ (๊ฐ™์€ ๊ฒฐ๊ณผ ์ƒ๋žต)
โ€“ ๋‹ค๋ฅธ ์˜ˆ:
select name
from employee
where employeeID not in (6651, 1234);
74
โ€“ EXISTS keyword (IN ๊ณผ๋Š” ๋‹ฌ๋ฆฌ ์‚ฌ์šฉ)
โ€ข use data from the outer query in the subquery. = a correlated subquery.
โ€ข ์˜ˆ (outside assignment์— ๊ทผ๋ฌดํ•œ ์ ์ด ์—†๋Š” employee๋ฅผ ์ฐพ๊ณ ์ž ํ•จ)
select e.name, e.employeeID
from employee e
where not exists
(select *
from assignment
where employeeID = e.employeeID);
โ€“ Subquery์—์„œ, โ€ฆ
โ€ข e.employeeID comes from the outer query. For each row in the employee table,
we check the results of the subquery, and if there is no matching row (WHERE
NOT EXISTS), we add the employee's details to the result set.
โ€“ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ์•ž์„œ์˜ LEFT JOIN์„ ์ด์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. (์˜คํžˆ๋ ค ๋” ํšจ์œจ์ )
+---------------+------------------+
| name
| employeeID
|
+---------------+------------------+
| Ajay Patel
|
6651
|
โ€ฆ
+----------------+-----------------+
3 rows in set (0.00 sec)
โ€“ ALL, ANY, and SOME keywords
โ€ข Subquery์˜ ๊ฒฐ๊ณผ๋ฅผ ๋น„๊ต (์˜ˆ: Nora Edwards, hardest working programmer, wants
to establish that nobody works longer hours than the programmers.)
select e.name from employee e, assignment a
where e.employeeID = a.employeeID
and a.hours > all
(select a.hours
from assignment a, employee e
where e.employeeID = a.employeeID
and e.job='Programmer');
75
Using SELECT Statement Options
SELECT [STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS] [HIGH_PRIORITY]
[DISTINCT | DISTINCTROW | ALL]
select_expression,...
[INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
[FROM table_references
[WHERE where_definition]
[GROUP BY {unsigned_integer | col_name | formula} [ASC | DESC], ...]
[HAVING where_definition]
[ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...]
[LIMIT [offset,] rows | rows OFFSET offset]
[PROCEDURE procedure_name(argument_list)]
[FOR UPDATE | LOCK IN SHARE MODE]]
โ€ข
โ€ข
STRAIGHT JOIN ; force query optimizer to join the tables in the order specified. (=extension to ANSI SQL)
SQL_SMALL_RESULT, SQL_BIG_RESULT, SQL_BUFFER_RESULT options ; optimization ์šฉ
โ€“
โ€“
โ€ข
โ€ข
SQL_CACHE and SQL_NOCACHE ; ๊ฒฐ๊ณผ์น˜๋ฅผ cache ์ฒ˜๋ฆฌํ•  ๊ฒƒ์ธ์ง€์˜ ์ง€์ •. (extension to ANSI SQL.) ??
SQL_CALC_FOUND_ROWS ; (LIMIT clause์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ. )
โ€“
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
SQL_SMALL_RESULT and SQL_BIG_RESULT; tells MySQL that you expect the result set to have either few rows or a large
number of them.
SQL_BUFFER_RESULT; put the result set into a temporary table. (๊ฒฐ๊ณผ๋ฅผ client์— ๋ณด๋‚ด๋Š”๋ฐ ๋„ˆ๋ฌด ๋งŽ์€ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜๋Š” ๊ฒฝ์šฐ) (=
MySQL extensions to ANSI SQL)
it tells MySQL to work out how many rows would have been returned if there had been no LIMIT clause. We can then
retrieve this number with select found_rows(); (another extension to ANSI SQL). In versions without it, a common task is to
run a COUNT(*) query and then a SELECT with a LIMIT.
HIGH PRIORITY; priority over any UPDATE statements that are waiting to use the involved tables.
DISTINCTROW = DISTINCT (๋‹จ, ALL is the opposite (return all duplicates) and is the default option.)
SELECT INTO OUTFILE ; SELECT ๋ฌธ์˜ ๊ฒฐ๊ณผ๋ฅผ ์ง€์ •๋œ file๋กœ ๋ณด๋ƒ„.(LOAD DATA INFILE ์˜ ๋ฐ˜๋Œ€)
export_options = options in LOAD DATA INFILE (see Chapter 5 for details).
PROCEDURE ; ๊ฒฐ๊ณผ๊ฐ€ client์— ๋ณด๋‚ด์ง€๊ธฐ ์ „์— ์ˆ˜ํ–‰๋˜์–ด์งˆ procedure ์ง€์ • (C++)
FOR UPDATE and LOCK IN SHARE MODE ; storage engine์ด page- or row-level locking์„ ์‚ฌ์šฉํ•  ๋•Œ๋งŒ ์˜ํ–ฅ.
โ€“
โ€“
76
์‹ค์ œ๋กœ๋Š” InnoDB ์™€ BDB.
(If you specify FOR UPDATE, you will set an exclusive lock, and if you use LOCK IN SHARE MODE, you will set a shared lock. )
8. ๋‚ด์žฅํ•จ์ˆ˜์™€ SELECT์˜ ์ด์šฉ
77
โ€ข (์ผ๋ฐ˜๋ก ) โ€ฆ
โ€“ โ€ฆ
โ€“ MySQL์—์„œ๋Š” any expression containing NULL will evaluate
to NULL, with a few exceptions.
โ€“ SELECT ๋ฅผ basic calculator๋กœ ์‚ฌ์šฉ๋„ ๊ฐ€๋Šฅ.
select 2+2; ๏ƒจ
+-------+
| 2+2 |
+-------+
| 4
|
+-------+
1 row in set (0.42 sec)
78
Operators
โ€ข
Arithmetic Operators
โ€ข
Comparison Operators
โ€“ +, -, *, / (๋‹จ,Division by zero produces a safe NULL result.)
โ€“ ํŠน์ด์ (1): ์ผ๋ถ€ ์˜ˆ์™ธ๋ฅผ ๋นผ๊ณ  comparing anything to NULL gives a NULL result.
(NULL๊ณผ NULL์˜ ๋น„๊ต ํฌํ•จ):
select NULL=NULL;
+----------------+
| NULL=NULL
|
+----------------+
|
NULL
|
+----------------+
1 row in set (0.00 sec)
โ€“ ๋น„๊ต: NULL์ด ํฌํ•จ๋œ ๋น„๊ตoperator์‚ฌ์šฉ ์‹œ์—๋Š” ์ฃผ์˜ํ•  ๊ฒƒ
select NULL IS NULL;
+-------------------+
| NULL IS NULL
|
+-------------------+
|
1
|
+-------------------+
1 row in set (0.00 sec)
โ€“ ํŠน์ด์ (2)
โ€ข MySQL์—์„œ ๋Œ€๋ถ€๋ถ„์˜ string comparisons ๋Š” case insensitive ์ด๋ฏ€๋กœ case-sensitive ํ•„์š” ์‹œ
๋Š” prefix one of them with the keyword BINARY. ์˜ˆ:
select * from department where name='marketing';
โ‰  select * from department where name = binary 'marketing'; ๏ƒจ
โ€ข <๊ณ„์†>
79
Table 8.1. Comparison Operators
Operator
Meaning
=
Equality
!= or <>
Inequality
<
Less than
<=
Less than or equal to
>
Greater than
>=
Greater than or equal to
n BETWEEN
min AND max
Range testing
n IN (set)
Set membership. Can be used with a list of literal values or expressions or with a subquery as the
set. ์˜ˆ: (apple, orange, pear)
<=>
NULL safe equal. This will return 1 (true) if we compare two NULL values
n IS NULL
test for a NULL value in n
ISNULL(n)
test for a NULL value in n
80
โ€ข
Logical Operators
โ€“ MySQL interprets any nonzero, non-null value as true.
โ€“ Logical expressions in MySQL can evaluate to 1 (true), 0 (false), or NULL.
โ€“ NULL ์ด ๊ด€๋ จ๋œ ๊ฒฝ์šฐ ์ผ๋ฐ˜์ ์ธ ์ง„๋ฆฌํ‘œ (truth table)์™€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.
Table 8.2. Logical Operators
Operator ์˜ˆ
์˜๋ฏธ
์ง„๋ฆฌํ‘œ
AND or &&
n && m
Logical AND
true&&true = true
false&&anything = false
All other expressions evaluate to NULL.
OR or ||
n || m
Logical OR
true || anything = true
NULL||false = NULL
NULL||NULL = NULL
false||false = false
NOT or !
NOT n
Logical NOT
!true = false
!false = true
!NULL = NULL
XOR
n XOR m
Logical exclusive OR
true XOR true = false
true XOR false = true
false XOR true = true
NULL XOR n = NULL
n XOR NULL = NULL
81
Control Flow Functions
โ€ข IF (e1, e2, e3)
โ€“ If e1 ์ด true์ด๋ฉด e2๋ฅผ returnํ•˜๊ณ  otherwise, it returns e3.
select name, if(job='Programmer', "nerd", "not a nerd")
from employee; ๏ƒจ
+-------------------+-----------------------------------------------------+
| name
| if(job='Programmer', "nerd", "not a nerd")
|
+------------------+------------------------------------------------------+
| Ajay Patel
| nerd
|
โ€ฆ
+------------------+------------------------------------------------------+
4 rows in set (0.00 sec)
โ€ข CASE
โ€“ ์˜ˆ:
CASE value
WHEN [compare-value] THEN result
[WHEN [compare-value] THEN result ...]
[ELSE result]
END
CASE
WHEN [condition] THEN result
[WHEN [condition] THEN result ...]
[ELSE result]
END
select workdate, case
when workdate < 2000-01-01 then "archivedโ€œ
when workdate < 2003-01-01 then "oldโ€œ
else "currentโ€œ
end
from assignment;
82
โ€ข /* Assignments from the last century are categorized as "archived", ones prior
to this year are categorized as "old", and everything else is "current". */
String Functions
Table 8.3. String Processing Functions
Function
Purpose
concat(s1, s2, ...)
Concatenate the strings in s1, s2, ....
conv (n, original_base,
new_base)
Convert the number n from original_base to new_base. (It may surprise you to see this as a string
function, but some bases use letters in their notations, such as hexadecimal.)
length(s)
Returns the length in characters of the string s.
load_file(filename)
Returns the contents of the file stored at filename as a string.
locate(needle, haystack,
position)
Returns the starting position of the needle string in the haystack string. ๊ฒ€์ƒ‰ ์‹œ์ž‘์€ position๋ถ€ํ„ฐ.
lower(s) and upper(s)
Convert the string s to lowercase or uppercase.
quote(s)
Escapes a string s so that it is suitable for insertion into the database. This involves putting the string
between single quotes and inserting a backslash.
replace(target, find, replace)
Returns a string based on target with all incidences of find replaced with replace.
soundex(s)
Returns a soundex string corresponding to s. A soundex string represents how the string sounds
when pronounced. It can be easier to match soundex strings of names than names themselves.
substring (s, position,
length)
Returns length characters from s starting at position.
trim(s)
Removes leading and trailing whitespace from s. ((์ฐธ๊ณ ) use ltrim() to just remove whitespace
83 from
the left or rtrim() for the right.)
String Comparison Functions
โ€ข Using LIKE for Wildcard Matching
select *
from department
where name like '%research%';
/* names containing 'research'. */
+--------------------+------------------------------------+
| departmentID
| name
|
+-------------------+-------------------------------------+
|
128
| Research and Development
|
+-------------------+-------------------------------------+
1 row in set (0.04 sec)
โ€“ two kinds of wildcard matching.
โ€ข %; matches any number of characters (including zero).
โ€“ '%research%' matches all strings that have the word research in them
somewhere. (case insensitive)
โ€ข underscore (_); matches any single character.
โ€“ '_at' matches the strings 'cat', 'mat', 'bat', and so on.
84
โ€ข Using RLIKE for Regular Expression Matching
โ€“ to match on the basis of regular expressions.
โ€ข regular expression = a pattern that describes the general shape of a string.
โ€ข List of strings
โ€“ The pattern 'cat' matches 'catโ€˜, but also 'catacomb' and 'the cat sat on the mat'.
โ€“ If we want to match only the word 'cat', then the pattern would need to be '^cat$'. The
caret (^) means "anchor to the start of the string;" (=the first thing at the start of a
matching string is the word 'catโ€˜). The dollar sign ($) means "anchor to the end of the
string;" (=the last thing in the string must be the word 'catโ€˜).
๏ƒŸ '^cat$' can match only the string 'cat' and nothing else.
โ€“ ๋‹จ, ์˜ค์ง ํ•œ ๊ฐœ์˜ wildcard ์ง€์›: the dot (.), that will match any single character.
» '.at' matches 'cat', 'bat', 'mat' and so on ๏ƒ  specify how often characters (wildcard ํฌํ•จ)
can appear in a string. (์˜ˆ:'n*' matches '', 'n', 'nn', 'nnn', โ€ฆ)
» '(cat)*โ€˜;matches '', 'cat', 'catcat', 'catcatcat', and so on.
โ€“ '.*' ; matches any number of any charactersโ€”basically anything.
โ€“ (+) ; means that the character or string before it should be repeated one or more times,
โ€“ (?) ; means to match zero times or one time.
โ€“ You can also list a specific range, so, for example, '(cat)(2,4)' matches 'catcat', 'catcatcat',
and 'catcatcatcat'.
โ€ข ๋˜ํ•œ list sets of characters.
โ€“ '[a-z]' matches any single letter, and '[a-z]*' matches any number of letters.
โ€ข character class=predefined set. ์˜ˆ:[[:alnum:]] matches any alphanumeric character.
โ€ข (๋‹จ, MySQL uses POSIX-style regular expressions โ‰  Perl regular expressions.
โ€“ ์˜ˆ:
select * from department where name rlike 'an'; /* containing 'an' inside them:*/๏ƒจ
+-------------------+--------------------------+
| departmentID | name
|
+-------------------+--------------------------+
โ€ฆ.
85
+-------------------+--------------------------+
3 rows in set (0.00 sec)
โ€ข
Using STRCMP() for String Comparison
โ€“ STRCMP(s1, s2) returns the following values:
โ€ข 0 if the strings are equal
โ€ข -1 if s1 is less than s2? that is, if it comes before s2 in the sort order
โ€ข 1 if s1 is greater than s2? that is, if it comes after s2 in the sort order
โ€ข ์˜ˆ:
select strcmp('cat', 'cat');
+-----------------------+
| strcmp('cat', 'cat') |
+----------------------+
|
0
|
+----------------------+
1 row in set (0.42 sec)
select strcmp('cat', 'dog');
+-----------------------+
| strcmp('cat', 'dog') |
+-----------------------+
|
-1
|
+-----------------------+
1 row in set (0.00 sec)
select strcmp('cat', 'ant');
+-----------------------+
| strcmp('cat', 'ant') |
+-----------------------+
|
1
|
+-----------------------+
1 row in set (0.00 sec)
โ€“ (์ฐธ๊ณ ) sort order changes with the character set. ๏ƒŸ internationalization
86
Numeric Functions
Table 8.4. Numeric Functions
Function
Purpose
abs(n)
absolute value of n
ceiling(n)
the value of n rounded up to the nearest integer.
floor(n)
the value of n rounded down to the nearest integer.
mod(n,m)
and div
divide n by m.
๋‹จ, div returns the integral quotient, and mod() returns the integral remainder.
power(n,m)
Returns n to the power of m.
rand(n)
Returns a random number between 0 and 1. parameter n ์€ optional๋กœ์„œ pseudorandom number ์ƒ์„ฑ์˜
seed๋กœ ์‚ฌ์šฉ (Giving the same n to rand will produce the same pseudorandom number.)
round(n[,d])
Returns n rounded to the nearest integer. If you supply d, n will be rounded to d decimal places.
sqrt(n)
Returns the square root of n.
87
โ€“ ์ฃผ์˜:
โ€ข mod(9,2) or 9 mod 2 or even 9 % 2 ๋ชจ๋‘๊ฐ€ ๊ฐ€๋Šฅํ•˜์ง€๋งŒ
โ€ข 9 div 2 ๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค. (์˜ˆ: div(9, 2) ๏ƒ a syntax error.)
โ€“ mod and div in MySQL gives the following results:
mysql> select 9 mod 2;
+-----------+
| 9 mod 2 |
+-----------+
|
1
|
+-----------+
1 row in set (0.00 sec)
select 9 div 2;
+----------+
| 9 div 2 |
+----------+
|
4 |
+----------+
1 row in set (0.00 sec)
88
Date and Time Functions
Table 8.5 Date and Time Functions
Function
Purpose
adddate(date, INTERVAL n type) ๋ฐ
subdate(date, INTERVAL n type)
๏ƒ  add and subtract dates.
Type ; SECOND, MINUTE, HOUR, DAY, MONTH, YEAR, MINUTE:SECOND
(format of n should be 'm:s'), HOUR:MINUTE ('h:m'), DAY_HOUR ('d h'),
YEAR_MONTH ('y-m'), HOUR_SECOND ('h:m:s'), DAY_MINUTE ('d h:m'),
DAY_SECOND ('d h:m:s').
curdate(), curtime(), now()
๏ƒ  current date, time, and date and time, respectively
date_format(date, format) ๋ฐ
time_format(time, format)
๏ƒ  reformat dates & times to any format you like. (์˜ˆ)
date_format(workdate, '%W %D of %M, %Y'). (๏ƒ 'Monday 16th of June,
2003').
dayname(date)
๏ƒ  name of the day in date (for example, 'Monday').
extract(type FROM date)
๏ƒ value of type in date. (์˜ˆ: YEAR ๏ƒ  return the year from date.)
Type๋Š” adddate(), subdate()์—์„œ์™€ ๋™์ผ
unix_timestamp([date])
๏ƒ current Unix timestamp. (= 1970/1/1์ด๋ž˜๋กœ ๋ช‡ ์ดˆ)
๏ƒ If called with a date, this returns timestamp corresponding to that date.
89
โ€“ ์˜ˆ: start from the 1st of January 1999 and add 1 year and 6 months to it:
select adddate("1999-01-01", INTERVAL "1-6" YEAR_MONTH); ๏ƒจ
+----------------------------------------------------------------------------+
| adddate("1999-01-01", INTERVAL "1-6" YEAR_MONTH)
|
+----------------------------------------------------------------------------+
| 2000-07-01
|
+----------------------------------------------------------------------------+
1 row in set (0.41 sec)
โ€“ Unix timestamps are not humanly readable, but they are very compatible
with the APIs that come with other programming languages. (์˜ˆ: date()
function built into PHP)
โ€“ unix_timestamp() function๊ณผ ๋™์ผํ•œ query
select unix_timestamp(adddate("1999-01-01", INTERVAL "1-6" YEAR_MONTH));
+------------------------------------------------------------------------------------------+
| unix_timestamp(adddate("1999-01-01", INTERVAL "1-6" YEAR_MONTH))
|
+------------------------------------------------------------------------------------------+
|
962373600
|
+------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
90
Cast Functions
โ€ข ์˜ค์ง 2๊ฐœ์˜ cast ํ•จ์ˆ˜: cast() ์™€ convert().
โ€“ = typecasting (=ํ•˜๋‚˜์˜ type (์˜ˆ: signed integer)์—์„œ ๋‹ค๋ฅธ
type(์˜ˆ: char)์œผ๋กœ ๋ณ€ํ™˜ (convert))
/* Syntax๋Š” ์•ฝ๊ฐ„ ๋‹ค๋ฅด์ง€๋งŒ ๋™์ผํ•œ ์ž‘์—….*/
โ€“ Prototypes:
โ€ข cast(expression AS type)
โ€ข convert(expression, type)
/* ANSI compliant, */
/* ODBC compliant.*/
โ€“ Valid types: BINARY, CHAR, DATE, DATETIME, SIGNED
(INTEGER), UNSIGNED (INTEGER).
โ€“ MySQL์—์„œ๋Š” ๋Œ€๋ถ€๋ถ„์˜ casting์ด ์ž๋™์ ์œผ๋กœ ์‹คํ–‰๋จ.
โ€ข ์˜ˆ; string ํ•จ์ˆ˜์— ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๏ƒ  ์ž๋™์œผ๋กœ string์œผ๋กœ cast ๋จ.
91
Other Functions
Table 8.6. Miscellaneous Functions
Function
Purpose
benchmark(count,
expression)
Evaluates expression count times. Always returns zeroโ€”the point of this function is to time
execution and look at the execution time at the bottom of the result set.
encrypt(s[,salt])
Encrypts s using a Unix crypt system call. The salt string is an optional two-character string.
If crypt is not available on your system (for example, Windows), this function will return NULL.
found_rows()
Returns the number of rows that would have been returned by the last query if no limit
clause was used. (SELECT๋ฌธ์—์„œ SQL_CALC_FOUND_ROWS ๊ฐ€ ๋ช…์‹œ๋˜์—ˆ์„ ๋•Œ๋งŒ ์œ ํšจ) as in Ch 7.
last_insert_id()
Returns the last automatically generated AUTO_INCREMENT value.
ํ•œ table์— row insertํ•œ ํ›„ ๊ทธ row์˜ id๋ฅผ ๋‹ค๋ฅธ table์˜ foreign key ๋กœ์„œ insertํ•˜๋ ค๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉ.
md5(s)
Returns the 128-bit MD5 hash of string s.
username ๊ณผ password๋ฅผ ์ €์žฅํ•˜๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ์ž‘์„ฑ์‹œ ์œ ์šฉ.
password(s)
Calculates a password string for the string s. (Chapter 11)
ํ”„๋กœ๊ทธ๋žจ ๋‚ด์—์„œ password๋ฅผ ๋ณด๊ด€ํ•˜๋Š” ๊ฒฝ์šฐ์— ์ด์šฉ.
92
Functions for Use with GROUP BY Clauses
โ€“ = grouping functions = aggregate functions.
โ€“ ๋˜ํ•œ query์˜ ๊ฒฐ๊ณผ ์ „์ฒด์— ๋Œ€ํ•ด ์ˆ˜ํ–‰ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. (์ „์ฒด rows๋ฅผ single group์ทจ๊ธ‰) ์˜ˆ:
select job, count(job)
from employee
group by job;
select count(*)
from employee; /* ๏ƒ  count the number of rows */
Table 8.7. Grouping Functions
Function
Purpose
avg(column)
Returns the average value in column.
count(column)
Returns the number of values in column.
min(column)
Returns the smallest value in column.
max(column)
Returns the largest value in column.
std(column)
Returns the standard deviation of the values in column.
sum(column)
Returns the sum of values in column.
93
9. MySQL Table Type์ดํ•ด
94
๊ธฐ์ดˆ
โ€ข DB์„ค๊ณ„
โ€“ trade-offs ; (์˜ˆ: a transaction-safe ๏ƒ  ์†๋„์ €ํ•˜, ๋””์Šคํฌ, ๋ฉ”๋ชจ๋ฆฌ ๋ถ€๋‹ด)
โ€“ ์ตœ์ข… ๊ฒฐ์ •์€ DB์„ค๊ณ„์ž
โ€ข (์šฉ์–ด)
โ€“ table types = storage engines
โ€“ This reflects
โ€ข DB์˜ ๋ณธ์งˆ์  ๋ชฉ์ ์€ ๋ฐ์ดํ„ฐ ์ €์žฅ.
โ€ข Caching, indexing, locking, and disk access๋“ฑ์„ ์ฒ˜๋ฆฌํ•˜๋Š” source code๋Š”
ํŠน์ •๋˜์–ด ์žˆ๋‹ค.
โ€“ transaction or transaction safe
โ€ข ์˜ˆ: ์€ํ–‰ ์ž๊ธˆ์ด์ฒด ๏ƒ  at least two SQL queriesโ€”one to deduct, and one to
add to the other. ๏ƒจ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์ผ๊ด€์„ฑ ์žˆ๋Š” ์ƒํƒœ (a consistent state)
๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” either both happen or both fail.
โ€“ Transaction-safe tables
โ€ข ๏ƒ  a set of queries is one indivisible unit of workโ€”a transaction. The
whole transaction should complete, or the database must roll back or
return to the same state it was in before the transaction started.
โ€ข MySQL์—์„œ ์ด์šฉ ๊ฐ€๋Šฅํ•œ table types๋Š”
โ€“ ISAM/ MyISAM/ InnoDB/ BerkeleyDB (BDB)/ MERGE/ HEAP
โ€ข ์ด ์ค‘์—์„œ:
โ€“ InnoDB and BerkeleyDB are transaction safe. (๋‚˜๋จธ์ง€๋Š” X)
โ€“ ๊ฐ€์žฅ ๋งŽ์ด ์ด์šฉ๋˜๋Š” ๊ฒƒ: MyISAM and InnoDB.
95
ISAM Tables
โ€ข MySQL์— ๋‚ด์žฅ ์‹œํ‚จ ๊ฒƒ์€ ๋‹จ์ง€ legacy support๋ฅผ ์œ„ํ•œ ๊ฒƒ
โ€“ > MyISAM table์ด ์™„์ „ ๋Œ€์ฒด -- ์—ฌ๊ธฐ์„œ ์–ธ๊ธ‰ ์ƒ๋žต.(ver. 5.0์—์„œ ์™„์ „ํžˆ ์—†์ด์งˆ ๊ฒƒ)
โ€ข ISAM
โ€“ ISAM table ์ƒ์„ฑ (just for reference) :
create table asset
(
assetID int not null,
description varchar(255)
) type=ISAM;
โ€“ ISAM table์ด ์กด์žฌํ•˜์ง€๋งŒ ์‹ ๊ทœ ๊ฐœ๋ฐœ์—๋Š” ์ด์šฉX ๊ฐ€๊ธ‰์  MyISAM์œผ๋กœ ์ „ํ™˜ํ•  ๊ฒƒ
โ€ข MyISAM
โ€“ ์žฅ์ :
โ€ข ISAM table์€ ๋น ๋ฅด์ง€๋งŒ transaction-safe storage๋ฅผ ์ œ๊ณตํ•˜์ง€ ๋ชปํ•จ.
โ€ข Table portability. -- ๋””์Šคํฌ ์ƒ์˜ Table์€ (์–ด๋–ค ํ”Œ๋žซํผ์ด๋“ ์ง€) ๋‹ค๋ฅธ ์‹œ์Šคํ…œ์œผ๋กœ load๋  ์ˆ˜
์žˆ์ง€๋งŒ ISAM table์€ X
โ€ข Support for very large tables. โ€“ OS ํ•œ๋„ ๋‚ด์—์„œ ๋ฌด์ œํ•œ โ€“ ์‹ค์ œ๋กœ๋Š” ๋Œ€๋ถ€๋ถ„ file system์ด
์ตœ๋Œ€ 2GB size (MERGE tabe์„ ์ด์šฉํ•ด์„œ ์ด ํ•œ๋„๋ฅผ ํšŒํ”ผ.) (Cf. ISAM tables; max 4GB.)
โ€ข ๋””์Šคํฌ ๊ณต๊ฐ„์„ ๋ณด๋‹ค ํšจ์œจ์ ์œผ๋กœ ์ด์šฉ ๏ƒŸ space ๋ฐ fragmentation์ด ์ค„์–ด ๋“ฌ
โ€ข Less restricted keys. - MyISAM tables ; 64 keys/table, a default max key ๊ธธ์ด=
1024 bytes. (cf. ISAM tables ; 16 keys/table, a default max key length=256 bytes.)
96
MyISAM Tables
โ€ข ๋น ๋ฅด์ง€๋งŒ transaction-safe storage๋Š” ์•„๋‹˜.
โ€“ (MyISAM table์„ ์ƒ์„ฑํ•˜๋Š” ์ฝ”๋“œ)
create table article (
articleID int not null auto_increment primary key,
title varchar(255),
body text
); /* ๋˜๋Š”) type=MyISAM; */
โ€ข MyISAM table types:
โ€ข ๏ƒŸ Column์ง€์ •์— ๋”ฐ๋ผ ์ž๋™์ ์œผ๋กœ ๊ฒฐ์ •๋จ.
โ€“ The char and numeric types ๏ƒ  ๊ณ ์ •๋œ ํฌ๊ธฐ.
โ€“ The size of varchar, text, blob columns ๏ƒ  ๋‚ด์šฉ์— ๋”ฐ๋ผ ํฌ๊ธฐ๊ฐ€ ๋‹ฌ๋ผ์ง.
โ€“ Dynamic
โ€“ Static
โ€“ compressed
โ€ข To repair or defragment a MyISAM table,
โ€“ myisamchk (command-line) ๋˜๋Š” REPAIR TABLE (MySQL ๋ช…๋ น์–ด). (Ch 13)
โ€ข To defragment but not repair,
โ€“ OPTIMIZE TABLE(MySQL command) ์ด์šฉ (Ch 18)
97
โ€“ Dynamic
โ€ข tables with variable-length rows will be created as dynamic tables.
โ€ข (cache, find, ๋˜๋Š” record์˜ repair ๋“ฑ์— ์žˆ์–ด) ๋ณด๋‹ค ๋ณต์žกํ•œ ๊ด€๋ฆฌ๊ฐ€ ํ•„์š”.
โ€“ ๏ƒŸ ํฌ๊ธฐ๊ฐ€ ๋ณ€ํ™”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๊ธฐ๋„ ํ•˜์ง€๋งŒ + fragmented๋˜๊ธฐ ๋•Œ๋ฌธ
» Corruption์„ ๊ณ ์น˜๊ธฐ ์–ด๋ ต๋‹ค.
» ๏ƒ a segment of a file that has been cached by the operating system
cannot be guaranteed to contain all parts of a row.
โ€“ Static
โ€ข Tables with fixed-length rows will be created as static tables
โ€ข ์žฅ์ .
โ€“ ๋‹ค๋ฅธ tableํ˜•์‹๋ณด๋‹ค search๊ฐ€ ๋น ๋ฅด๋‹ค.
» ๏ƒŸ Index๋ฅผ ํ†ตํ•ด record๋ฅผ retrieveํ•  ๋•Œ ๊ทธ ์œ„์น˜๊ฐ€ ํŒŒ์ผ ์‹œ์ž‘์ ์œผ๋กœ๋ถ€ํ„ฐ ํŠน์ •
offset์œผ๋กœ ์ •ํ•ด์ง.
» ๏ƒŸ It is very easy to cache.
» ๏ƒŸ It is less likely to suffer serious corruption in the event of a crashโ€”
the repair facility can usually recover all rows except the damaged one.
โ€ข Disadvantage
โ€“ ๋Œ€๋ถ€๋ถ„ disk space์˜ ๋‚ญ๋น„๋ฅผ ์ดˆ๋ž˜. (๋Œ€์ƒ column์— ๋”ฐ๋ผ ๊ทธ ์ •๋„๊ฐ€ ๋‹ค๋ฅด๋‹ค.)
โ€“ compressed
โ€ข ์ธ์œ„์ ์œผ๋กœ myisampack tool์„ ์ด์šฉํ•˜์—ฌ ์ƒ์„ฑ.
98
โ€ข Compressing MyISAM Tables
โ€“ Table type์€ ์ž๋™์œผ๋กœ ๊ฒฐ์ •๋˜์ง€๋งŒ table compression์€ ์ž๋™์ด ์•„๋‹˜.
๏ƒŸ myisampack. (๋‹จ, pure ISAM table์˜ ๊ฒฝ์šฐ pack_isam ์ด์šฉ)
โ€“ Compression ์€ ์ข‹์€ ๊ฒƒ์ฒ˜๋Ÿผ ๋“ค๋ฆด ์ˆ˜ ์žˆ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์ผ๋ถ€์—๋งŒ ํ•ด๋‹น
โ€ข ๏ƒŸ compressed tables become read-only.
โ€“ Table์„ alter, update, or insert data ํ•  ๊ฒฝ์šฐ ์ „์ฒด table์„ uncompressํ•˜๊ณ 
๋ณ€๊ฒฝํ•œ ํ›„ ๋‹ค์‹œ recompress the table.
โ€“ myisampack์— ์˜ํ•œ compression์€ ๋‹ค์Œ์˜ ํ˜ผํ•ฉ ์ž‘์šฉ:
โ€ข true compression (Huffman coding)
โ€ข + a set of optimizations aimed at shrinking columns, such as
โ€“ converting types to smaller types and
โ€“ converting columns to enums.
โ€“ record ๋ณ„๋กœ ๊ฐ๊ฐ compress๋˜๋ฏ€๋กœ ์‹ค์ œ๋กœ overhead๋Š” ๊ทธ๋ฆฌ ํฌ์ง€ ์•Š๋‹ค.
This may even be counterbalanced on slow devices by the
reduction in data that needs to be read from disk.
99
โ€ข
Full-Text Searching on MyISAM Tables
โ€“ ์˜ˆ: create a MyISAM table with a full-text index:
create table article (
articleID int not null auto_increment primary key,
title varchar(255),
body text,
fulltext (title,body));
โ€“ ์˜ˆ: retrieve any records containing the word 'merger':
select title from article
where match (title,body) against ('merger');
โ€“ ์˜ˆ: ๋‹ค์Œ ๋ฌธ์ž ํฌํ•จํ•˜๋Š” record ;'mergeโ€˜ or 'acquisitionโ€˜ or 'acquireโ€˜ or 'takeover'.
select title from article
where match (title,body) against ('merge acquisition acquire takeover');
โ€ข /* ๋‹จ, we are matching any record that contains at least one of the words. (string or record
containing every word listed ๊ฐ€ ์•„๋‹˜. ๋’ค์— ๋‚˜์˜ด)
โ€“ 'acquireโ€˜์™€ 'acquisitions' ๋Š” ๋ณ„๊ฐœ๋กœ ๊ฒ€์ƒ‰ํ•  ๊ฒƒ. ์™œ๋ƒํ•˜๋ฉด MySQL์ด stemming์„ ์ง€์›x.
โ€ข Stemming; ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋‹จ์–ด์— ๋Œ€ํ•œ ์–ด๊ทผ (stem word)์„ ํ†ตํ•œ ๊ฒ€์ƒ‰. (์˜ˆ: 'acquire' is the stem of many
words such as 'acquires', 'acquired', and 'acquisition'.)
โ€“ match ๋˜๋Š” ๊ฒƒ์œผ๋กœ ๋ฐœ๊ฒฌ๋œ ํ•ญ๋ชฉ์—๋Š” relevance value๊ฐ€ ๋งค๊ฒจ์ง€๊ณ  ๊ทธ์— ๋”ฐ๋ผ ์ž๋™ sorting๋œ.
โ€ข You may want to see the relevance scores for records.
โ€“ ์˜ˆ: retrieve an unsorted list of scores for all records. Any records with a score of zero
have no similarity and will not be retrieved.
select title, match (title,body)
against ('merge acquisition acquire takeover')
as relevance
from article;
โ€ข /* ๋‹จ, relevance ๋Š” keyword๊ฐ€ ์•„๋‹ˆ๋ผ just an alias for match(title,body) against ('merge acquisition
100
acquire takeover')*/
โ€“ ์˜ˆ: retrieve article titles and scores for matched documents.
select title, match (title,body)
against ('merge acquisition acquire takeover')
as relevance
from article
where match (title,body) against ('merge acquisition acquire takeover');
โ€“ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์—†๋Š” ๋‹จ์–ด:๏ƒŸ ์„ฑ๋Šฅ๋ฌธ์ œ ๋“ฑ
โ€ข Short words are not indexed.
โ€“ 4 characters (default) ๋ฏธ๋งŒ์€ ๋ฌด์‹œ. For some installations, most famously Slashdot.org,
this is a problem because three-letter acronyms are often an important part of the
content in technical material. You can change this limit by altering the variable
ft_min_word_len, but you will need to regenerate your indexes.
โ€ข Stop word = a word with no semantic value. ๋ฌธ์žฅ๊ตฌ์„ฑ์—๋Š” ์ค‘์š”ํ•˜๋‚˜ ์ปจํ…์ธ ์—์„œ๋Š”
์ค‘์š”์น˜ ์•Š์€ ๊ฒƒ. (์˜ˆ: 'the', 'and', 'then', and 'soon' ) ํ‘œ์ค€์˜ stop word์™ธ์—๋„ ๋ณ„๋„
์ง€์ • ๊ฐ€๋Šฅ.
โ€“ ์ฐธ๊ณ :full-text indexing์€ ๋ณต์žกํ•œ ์ž‘์—…. ๊ทœ๋ชจ๊ฐ€ ์ปค์ง€๋ฉด (์˜ˆ: > 1 M row) ์„ฑ๋Šฅ์ €ํ•˜.
โ€“ Words that are common in your data are not used when searching.
โ€ข ์˜ˆ: Table์— company newsletter articles for Acme PTY Ltd.์ด ํฌํ•จ๋˜๋ฉด 'Acme'๋ผ๋Š”
๋ง์ด ๋ฐ˜๋ณต๋˜๊ธฐ ์‰ฝ๋‹ค. If 50% or more of your records contain a word, that word is
taken to have no value when calculating relevance.
101
โ€ข Boolean Full-Text Search
โ€“ ์˜ˆ: match only records that contain the word 'linux' and the string "Open
Source", but not the word 'desktop'. ๋˜ํ•œ 'Java' ์™€ 'Oracleโ€˜์€ optional. ๊ทธ
๋ฆฌ๊ณ  ์ด๋•Œ record์— 'Javaโ€˜๊ฐ€ ํฌํ•จ๋˜๋ฉด relevance๊ฐ€ ์˜ฌ๋ผ๊ฐ€๊ณ 'Oracle' ์ด ํฌํ•จ๋˜
๋ฉด degrade the ranking. search string ์—์„œ์˜ ๋‹จ์–ด ๋˜๋Š” record์˜ ์ˆœ์„œ๋Š” ์ค‘์š”
ํ•˜์ง€ ์•Š์Œ.
select title
from article
where match (title,body)
against ('+linux +"Open Source" -desktop Java ~Oracle' IN BOOLEAN MODE);
โ€“ Boolean mode๊ฒ€์ƒ‰์— ๋ฐ˜๋“œ์‹œ full-text index๊ฐ€ ํ•„์š”์น˜๋Š” ์•Š์ง€๋งŒ unindexed
table์˜ ๊ฒ€์ƒ‰์€ ๋งค์šฐ ๋Šฆ์–ด์ง.
โ€“ ๋˜ํ•œ Boolean mode๋กœ ๊ฒ€์ƒ‰ ์‹œ์—๋Š” ํ”ํžˆ ๋‚˜ํƒ€๋‚˜๋Š” ๋‹จ์–ด๋„ ๋ฌด์‹œํ•˜์ง€ ์•Š๊ณ  ๊ฒ€์ƒ‰.
์ฆ‰, 50% rule does not apply.
โ€ข ์‹ ๋ฌธ์˜ article์—์„œ Acme PTY Ltd๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ์ฒซ์งธ query๋ฌธ์—์„œ๋Š” ๋Œ€๋ถ€๋ถ„์˜
row๊ฐ€ ์ถœ๋ ฅ๋˜์ง€๋งŒ ๊ทธ ๋‹ค์Œ์˜ query๋ฌธ์—์„œ๋Š” empty result set.
select title from article
where match (title,body) against ('Acme' IN BOOLEAN MODE);
select title from article
where match (title,body) against ('Acme');
102
Table 9.1. Boolean Mode Search Operators
Oper
ator
Meaning
+
This word is compulsory.
-
This word must not appear.
<
This word is less important.
>
This word is more important.
()
Group words together as a subexpression.
~
This word may appear, but it has a negative effect on ranking.
*
Wildcard suffix. ์˜ˆ: merge will not match merger, but merge* will match both
merge and merger.
May be used only at the end of a word.
""
This is a phrase. Matches only exactly the same content in the same order.
103
InnoDB Tables
โ€ข ์ผ๋ฐ˜๋ก 
โ€“ InnoDB is a fast, transaction-safe storage engine (Transactionsโ€“Ch 10)
โ€“ InnoBase Oy ์—ญ์‹œ dual-licensing. (www.innodb.com)
โ€“ ํŠนํžˆ ๋Œ€๋Ÿ‰ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ ์†์œผ๋กœ transaction-safe ํ™˜๊ฒฝ์—์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์šฉ.
โ€ข ์‚ฌ๋ก€: Slashdot (www.slashdot.org), Google (www.google.com), and Yahoo!
Finance (http://finance.yahoo.com)
โ€“ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ MyISAM์ด ๋‹ค์†Œ ๋น ๋ฅด๋‹ค.
โ€“ Row-level locking.
โ€ข ๏ƒ  only the row we are using in a particular query is unavailable to other users.
(BDB์ œ์™ธํ•œ) ๋Œ€๋ถ€๋ถ„ ๋‹ค๋ฅธ storage์—”์ง„์€ table-level locking, ์ฆ‰, while one process
is updating a table, it is not available to other processes.
โ€“ Support for foreign keys.
โ€“ Consistent nonlocking reads in SELECTs.
โ€ข (The idea for this is borrowed from Oracle.)
โ€ข InnoDB has its own configuration options, its own directory, and its
own way of storing data.
โ€“ Whereas MyISAM stores one table per file, InnoDB stores all its tables
and indexes in a tablespace, which means that they may be stored over
multiple files. This allows InnoDB to have very large tables that will be
unaffected by any operating-system file size restrictions.
โ€“ ๋‹จ, MyISAM์™€ ๋น„๊ตํ•˜์—ฌ ๋™์ผ record์ €์žฅ์— ํ›จ์”ฌ ๋งŽ์€ disk ๊ณต๊ฐ„ ์‚ฌ์šฉ.
104
BerkeleyDB (BDB) Tables
โ€ข BDB is provided by Sleepycat software (www.sleepycat.com).
โ€ข All BDB tables must have a primary key (not that this is much
of a problem because we would recommend this anyway). In
fact, one will be created silently for you if you do not create
one for yourself.
โ€ข ๊ทธ๋Ÿฌ๋‚˜ ๊ทธ๋ฆฌ ๋งŽ์ด ์“ฐ์ด์ง€ ์•Š์Œ.
โ€“
โ€“
โ€“
โ€“
BDB engine์€ ์˜ค๋ž˜ ์ „์— ๋‚˜์™”์ง€๋งŒ MySQL integration์€ ์ตœ๊ทผ.
page-level locking์ด๋ฏ€๋กœ InnoDB๋ณด๋‹ค ์„ฑ๋Šฅ์ด ๋‹ค์†Œ ๋–จ์–ด์ง
๋˜ํ•œ ๋งŽ์€ table์„ ๋™์‹œ์— ์—ด์–ด๋†“์œผ๋ฉด ์„ฑ๋Šฅ์ €ํ•˜.
BDB tables are stored as b-trees.
โ€ข ๋น„๊ต: ๋Œ€๋ถ€๋ถ„์˜ ๋‹ค๋ฅธ table types store their indexes as b-trees. ๏ƒ  table
scanning์ด ๋Šฆ์–ด์ง (such as when you are retrieving all rows from the
table or performing unindexed queries).
โ€“ BDB tables also take up more space on disk.
โ€“ you cannot move the stored data around on disk. ์™œ๋ƒํ•˜๋ฉด the
data stored for a table includes the path to the data.
โ€“ ๋˜ํ•œ be careful when backing up BDB tables to remember to back
up the log files because you will be unable to restart without them.
105
MERGE Tables
โ€ข maximum file size์— ๋Œ€ํ•œ ์šด์˜์ฒด์ œ์˜ ํ•œ๊ณ„๋ฅผ ๊ทน๋ณตํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ ์œ ์šฉ.
โ€“ Because each MyISAM table is stored in a single file, tables are limited in
size by the maximum file size of the operating system.
โ€“ MERGE table = a construct that allows you to treat multiple MyISAM
tables as a single table for the purpose of queries.
โ€ข ์˜ˆ: create a MERGE table consisting of three log tables (Listing 9.1)
โ€ข MERGE table์—์„œ๋„ ๊ฐ๊ฐ์˜ table์— ๋Œ€ํ•ด query ๊ฐ€๋Šฅ.
โ€ข ๋‹จ, We cannot DROP, ALTER, DELETE FROM TABLE, REPAIR,
TRUNCATE, OPTIMIZE, or ANALYZE any of the component tables.
You will be able to do some of these things (DELETE FROM TABLE)
if the MERGE table is not currently open. You can close it with
FLUSH TABLES.
โ€“ manual ์—์„œ๋Š” FLUSH ํ›„์— ์œ„์˜ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์ž˜ ์•ˆ๋จ
(*) ์˜ˆ; dropping one of the component tables leads to the MERGE table
also being silently dropped. If you need to make these sorts of changes,
you may be better off dropping the MERGE table and re-creating it.
Dropping the MERGE table does not affect the component tables or their
data.
โ€ข You can compress individual tables in the MERGE with myisampack.
์—ฌ๊ธฐ์„œ์˜ logfile ์˜ˆ์—์„œ ์œ ์šฉโ€”compress the earlier months' log files
because we are writing to only the most recent log.
106
Listing 9.1 A MERGE Table Example
create database logs;
use logs;
create table log2003Jan
(logid int auto_increment primary key,
logts datetime,
entry char(255));
insert into log2003Jan values
(NULL, '2003-01-01', 'first jan entry');
create table log2003Feb
(logid int auto_increment primary key,
logts datetime,
entry char(255));
insert into log2003Feb values
(NULL, '2003-02-01', 'first feb entry');
create table log2003Mar
(logid int auto_increment primary key,
logts datetime,
entry char(255));
insert into log2003Mar values
(NULL, '2003-03-01', 'first mar entry');
create table logs
(logid int auto_increment primary key,
logts datetime,
entry char(255))
type = merge
union = (log2003Jan, log2003Feb, log2003Mar)
insert_method = last;
๏ถ ๋™์ผํ•œ structure์˜ table 3๊ฐœ๋ฅผ ์ƒ์„ฑ (log2003Jan, โ€ฆ)
๏ถ Logging is a common application of MERGE tables.
๏ถ ๋ฐ์ดํ„ฐ ์ž…๋ ฅ ํ›„ MERGE table ์ƒ์„ฑ, by creating logs table.
(specifying that it is of type MERGE and that it is the
UNION of the three tables.)
๏ถ๋งจ ๋์˜ INSERT_METHOD ; if we insert data into the
MERGE table, it will be added to the last table in the merge,
in this case log2003Mar. The other options are FIRST
(insert into the first table in the list) or NO (don't allow
inserts into the MERGE table).
๏ถ ๏ƒจ a table that contains all the data in the merged tables.
๏ถ (์ค‘์š”) MERGE table์—์„œ์˜ primary key์ธ logid ๋Š” ์ผ๋ฐ˜์ ์ธ
primary key์˜ ์šด์šฉ๋ฐฉ์‹๊ณผ๋Š” ๋‹ค๋ฅด๋‹ค. Usually, they must be
unique, but because the MERGE table manages three sets
of primary keys, there may well be more than one row with
the same primary key, as in the preceding output.
(run the query)
select * from logs; ๏ƒจ
+-------+--------------------------+-------------------+
| logid | logts
| entry
|
+-------+--------------------------+-------------------+
| 1 | 2003-01-01 00:00:00 | first jan entry |
| 1 | 2003-02-01 00:00:00 | first feb entry |
| 1 | 2003-03-01 00:00:00 | first mar entry |
+-------+---------------------------+-------------------+
3 rows in set (0.01 sec)
107
HEAP Tables
โ€ข = extremely fast tables that are stored wholly in memory.
๏ƒŸ hashed indexing scheme ์ด์šฉ
โ€ข ์žฅ๋‹จ์ 
โ€“ ๋‹จ์ ; ์ „์›๋ฌธ์ œ ๋ฐœ์ƒ ์‹œ your HEAP data is gone forever.
โ€“ ์žฅ์ : temporary table ์ €์žฅ์— ์ ํ•ฉ.
โ€ข You can create a HEAP table like this:
โ€ข
โ€ข
โ€ข
โ€ข
create table testHeap
(id int not null primary key, data char(100))
type=heap
max_rows = 100;
โ€“ ์ด ์˜ˆ์—์„œ์ฒ˜๋Ÿผ max number of rows๋ฅผ limitํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. ๏ƒŸ HEAP
table์ด ์ปค์ง€๋ฉด ๊ณง๋ฐ”๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ๋ฌธ์ œ. The number of rows can also
be limited by the configuration directive max_heap_table_size.
โ€ข HEAP tables have a few limitations:
โ€“
โ€“
โ€“
โ€“
AUTO_INCREMENT ์ง€์›x
BLOB or TEXT type ์ง€์› x
HEAP tables cannot use the leftmost prefix of an index to find rows.
Indexes will be used only to find rows with queries that use the =
or <=> operators in the search clause.
108
10. InnoDB Table์„ ํ†ตํ•œ
Transaction ์ด์šฉ
109
Transaction์ด๋ž€?
โ€ข A transaction = a sequence of related instructions that must
be treated as one indivisible unit.
โ€“ (atomicity) A transaction cannot be broken down into partsโ€”It all
gets processed (done) or it all gets ignored (undone).
โ€“ ์˜ˆ: ์€ํ–‰ ๊ณ„์ขŒ๊ด€๋ฆฌ (bank account)
create table account
(
number int not null auto_increment primary key,
balance float
) type = InnoDB;
โ€ข (๊ทธ๋Ÿฐ ํ›„)
insert into account (balance) values (0.0);
insert into account (balance) values (1000.0);
insert into account (balance) values (2000.0);
โ€ข (๊ฒฐ๊ณผ)
+------------+-----------+
| number
| balance |
+------------+-----------+
|
1
|
0 |
|
2
|
1000 |
|
3
|
2000 |
110
โ€“ (๋‹จ์ˆœํ•œ ์‚ฌ๋ก€: deposit $500 into account 2)
# first check balance
select balance from account where number = 2;
# query gives us a result of $1000
# now store updated balance
update account set balance = 1500 where number = 2;
โ€“ These queries are related. They need to be run together.
โ€ข ๋งŒ์•ฝ ์ž”์•ก์กฐํšŒ์™€ update ์‚ฌ์ด์— balance๋ฅผ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด updateํ•œ๋‹ค๋ฉด ๋ฌธ์ œ!
โ€ข IF
query๋ฅผ ํ†ตํ•ด $500์„ ์˜ˆ๊ธˆํ•˜๊ณ  ๋‹ค๋ฅธ ๊ณ ๊ฐ์ด $100์„ ์˜ˆ๊ธˆํ•˜๋ ค ํ•œ๋‹ค๋ฉด
THEN ์ž”์•ก ๊ฒฐ๊ณผ์น˜๋Š” $1100 ๋„ ๋  ์ˆ˜ ์žˆ๊ณ  $1500๋„ ๋  ์ˆ˜ ์žˆ๋‹ค.
# first check balance
select balance from account where number = 2;
# query gives us a result of $1000
# now store updated balance
update account set balance = 1100 where number = 2;
โ€“ ๋‹จ, ์ด ๊ฒฝ์šฐ์—๋Š” ๋ฌธ์ œ๊ฐ€ ์‰ฝ๊ฒŒ ํ•ด๊ฒฐ๋  ์ˆ˜ ์žˆ๋‹ค.๏ƒŸ Make our updates
relative rather than absolute will make them into single, indivisible
units and will solve the problem.
โ€“ ๋‹ค์Œ query๋Š” (๋‹ค๋ฅธ query๊ฐ€ ๋™์‹œ ์‹คํ–‰๋˜๋˜์ง€ ๊ด€๊ณ„์—†์ด) ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
update account set balance = balance + 500 where number = 2;
โ€“ A single update statement in MySQL is always atomic. It cannot
be interrupted by another query or half succeed. It will complete
or will completely fail on an error.
111
โ€“ (๋ณต์žกํ•œ scenario) transfer $1000 from account 2 to account 1:
update account set balance = balance - 1000 where number = 2;
update account set balance = balance + 1000 where number = 1;
โ€“ 2๊ฐœ์˜ query๊ฐ€ ํ•จ๊ป˜ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค. ๏ƒ  ๊ฑฐ๋ž˜ ์ „ํ›„์˜ ์ด ๊ธˆ์•ก(total amount)๋Š” ๋™์ผ. ๋„์ค‘์—
power failure๊ฐ€ ๋ฐœ์ƒ ์‹œ data๊ฐ€ inconsistent! ๏ƒจ collapse queries into one SQL statement!
update account as source, account as dest
set source.balance = source.balance ?1000,
dest.balance = dest.balance + 1000
where source.number = 2 and dest.number = 1;
โ€“ account table์— ๋Œ€ํ•œ 2๊ฐœ์˜ aliases (source ๋ฐ dest)๋ฅผ ํ†ตํ•ด ํ•˜๋‚˜์˜ atomic update๊ฐ€ either
succeed or failํ•˜๋„๋ก ํ•˜์˜€๋‹ค. Readability๊ฐ€ ๋ฌธ์ œ์ผ ๋ฟ. ๊ทธ๋Ÿฌ๋‚˜ ๋งŽ์€ ๊ฒฝ์šฐ ๋ชจ๋“  ๊ด€๋ จ query๋“ค์„
์ด์ฒ˜๋Ÿผ collapse์‹œํ‚ค๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
โ€“ (solution) use MySQL's transaction syntax๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ๋ฌธ์žฅ์„ ํ•˜๋‚˜์˜ transaction (=a
related, indivisible set). ์œผ๋กœ ํ‘œ์‹œ
start transaction;
update account set balance = balance - 1000 where number = 2;
update account set balance = balance + 1000 where number = 1;
commit;
โ€“ (transaction์˜ ํŠน์ง•)
โ€ข they are not visible to other sessions until they are complete and committed. No other thread
can read inconsistent data from the table(s) while you are in the process of updating it.
โ€ข partially performed transactions can be undone. ๏ƒŸ roll back the transaction before we have
committed it ๏ƒ  changes made by queries that are part of the transaction will be undone.
โ€ข (์œ„์˜ ์˜ˆ์—์„œ SELECT ๋ฌธ์„ ํ†ตํ•ด ์ž”๊ณ ์ด์ƒ์˜ ์ธ์ถœ์„ ๋ชปํ•˜๊ฒŒ ํ•˜๋ฉด ๏ƒ  ROLLBACK๋ฅผ ํ†ตํ•ด cancel ๊ฐ€๋Šฅ)
start transaction;
update account set balance = balance - 1000 where number = 2;
update account set balance = balance + 1000 where number = 1;
select balance from account where number = 2;
# select tells us that account #2 has a negative balance!
# we'd better abort rollback;
โ€“ Calling ROLLBACK aborts the transaction and undoes any changes made. A transaction
that was rolled back instead of committed leaves no trace in the data. Because partial
results were never visible to other sessions, it is exactly as though it never happened.
112
Using Transactions in MySQL
โ€“ START TRANSACTION is synonymous with BEGIN or BEGIN WORK.
โ€ข ๋‹ค๋ฅธ DB ์‚ฌ์šฉ ๋“ฑ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€์ง€๋งŒ START TRANSACTION ๊ฐ€ SQL-99 syntax์ด๋ฏ€๋กœ ๊ถŒ์žฅ.
โ€ข Setting the Autocommit Mode
โ€“ ๋ณดํ†ต ๋•Œ ์ด๋ฏธ autocommit mode๋กœ ์ˆ˜ํ–‰โ€“๊ฐ query๋Š” ์‹ค์ œ ํ•˜๋‚˜์˜ isolated transaction.
(๋ชจ๋“  query์— ๋Œ€ํ•ด ์ž๋™์œผ๋กœ START TRANSACTION ๋ฐ COMMIT๊ฐ€ ์ ์šฉ๋œ ํšจ๊ณผ)
update account set balance = balance - 1000 where number = 2;
update account set balance = balance + 1000 where number = 1;
โ€“ ==
start transaction;
update account set balance = balance - 1000 where number = 2;
commit;
start transaction;
update account set balance = balance + 1000 where number = 1;commit;
โ€“ Note that if you manually type
start transaction; /* ๏ƒ  nothing will be committed until */
commit;
โ€“ To disable the autocommit behavior using the SET command:
set autocommit=0;
โ€ข ๏ƒ  ์ด ๊ฒฝ์šฐ์—๋Š” START TRANSACTION ์„ ์ด์šฉํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.
โ€ข (์ค‘์š”) ๋‹จ, ์ฃผ๊ธฐ์ ์œผ๋กœ COMMIT ๋ฅผ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ ์šฉํ•ด ์ค„ ๊ฒƒ.
โ€“ To put MySQL back into autocommit mode:
set autocommit=1;
โ€“ The autocommit variable is local to a single session
โ€ข changing the mode will affect only queries run from your session and only for
as long
113
as your session is connected.
โ€ข autocommit ๊ฐ€ on์ด๋“  off์ด๋“  ์ƒ๊ด€์—†์ด ๊ฐ„ํ˜น ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ์ž๋™์œผ๋กœ
์ ์šฉ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์ฆ‰, MyISAM๊ณผ ๊ฐ™์€ non-transaction-safe
table type์„ ์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋ชจ๋“  ๋ณ€๊ฒฝ์‚ฌํ•ญ์€ (autocommit setting
์— ์ƒ๊ด€์—†์ด) ์ฆ‰๊ฐ (immediately) commit๋œ๋‹ค.
โ€“ You can happily group your statements with START TRANSACTION
and COMMIT; it is just that this will have no effect on the nontransaction-safe tables.
โ€“ ์‹ฌ์ง€์–ด ROLLBACK์„ ํ˜ธ์ถœ(call)ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๏ƒ  ์‹คํ–‰์˜ค๋ฅ˜๊ฐ€ ๋˜์ง€๋Š” ์•Š๊ณ 
๋‹จ์ง€ ์•„๋ฌด๋Ÿฐ ํšจ๊ณผ๊ฐ€ ์—†์„ ๋ฟ.
โ€“ ๊ฐ๊ฐ ๋‹ค๋ฅธ table type์„ ๊ฐ€์ง„ ์„œ๋ฒ„์— dump file์„ reloadํ•˜๊ฑฐ๋‚˜ code
test ํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์šฉ.
โ€ข For transaction-safe tables, there are actions (other than
typing COMMIT) that will automatically trigger a COMMIT.
Requesting a lock will implicitly commit any outstanding
queries.
114
Locks์˜ ์ด์šฉ
โ€ข Table์„ manually lock and unlockํ•ด๋„ transaction์˜ ํšจ๊ณผ๋ฅผ
๊ฑฐ๋‘˜ ์ˆ˜ ์žˆ๋‹ค.
lock tables account write;
select balance from account where number = 2;
update account set balance = 1500 where number = 2;
unlock tables;
โ€“ ๋‹จ, ์ผ๋‹จ table์„ lockํ•˜๋ฉด ๊ฐ€๋Šฅํ•œ ๋นจ๋ฆฌ unlockํ•ด์•ผ ๋‹ค๋ฅธ thread์—
๋Œ€ํ•œ impact๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ Request all the locks you
need at once!
โ€ข ์•ž์„œ์™€ ๋‹ฌ๋ฆฌ ์—ฌ๋Ÿฌ ํ…Œ์ด๋ธ”์„ ์ด์šฉํ•˜๋ฉด์„œ lock์ด ํ•„์š”ํ•˜๋ฉด ํ•จ๊ป˜ ํ˜ธ์ถœ:
lock tables account write, account as a read, othertable
low_priority write;
โ€“ LOCK TABLES๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ธฐ์กด์˜ ๋ชจ๋“  lock์„ ํ•ด์ œ (release).
โ€ข ๏ƒ  If you attempt to collect the locks you need over multiple
statements, you will release all the early ones and will only
actually hold the locks requested in the final statement.
115
โ€ข (Lock์˜ ์ฃผ๋œ ์œ ํ˜•:= read and write.)
โ€“ ๊ธฐ๋ก์„ ์œ„ํ•ด table accessํ•  ๋•Œ write lockํ•˜๋ฉด ๋‹ค๋ฅธ ์–ด๋–ค thread๋„ read/write๊ฐ€
๋ถˆ๊ฐ€๋Šฅ (until you release it).
โ€“ A read lock is less extreme. ๋‹จ์ง€ table read๋งŒ ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๋‹ค๋ฅธ thread๊ฐ€ ๋™์‹œ
์— readํ•˜๋Š” ๊ฒƒ์€ ์ƒ๊ด€ ์—†๋‹ค. (๋‹จ์ง€ lock์„ ๊ฑด ๋™์•ˆ ๋‹ค๋ฅธ thread์˜ write๋งŒ ๊ธˆ์ง€)
โ€ข write lock์—์„œ low_priority๋กœ ํ‘œ์‹œ; ๋ˆ„๊ตฌ์—๊ฒŒ lock์˜ ์šฐ์„ ์ˆœ์œ„๋ฅผ ์ค„ ๊ฒƒ์ธ๊ฐ€์— ๋Œ€ํ•œ policy
๊ฐ€ ํ•„์š”.
โ€ข MySQL์€ ๋ณดํ†ต write lock request์— ๋Œ€ํ•ด read lock๋ณด๋‹ค ์šฐ์„ ๊ถŒ (priority)์„ ์ฃผ์–ด์„œ ๊ธฐ์กด
์ €์žฅ๋œ ๋ฐ์ดํ„ฐ์˜ update๊ฐ€ ๊ฐ€๊ธ‰์  ๋นจ๋ฆฌ ์ด๋ฃจ์–ด์ง€๋„๋ก ํ•จ. ๋งŒ์•ฝ ๋‹ค๋ฅธ ๋ฐฉ์‹์„ ์›ํ•œ๋‹ค๋ฉด you
can request a low-priority write lock (์•ž์˜ ์˜ˆ์—์„œ์˜ other table).
๋‹จ, ์ฃผ์˜: Lock์„ requestํ•  ๋•Œ๋งˆ๋‹ค ์ž ์‹œ waitํ•ด์•ผ ํ•œ๋‹ค. ๋˜ํ•œ low-priority lock will be
granted only if there are no other threads requesting read or write locks on that
table. It is possible on a busy server that this might never happen.
โ€“ ๊ฐ„ํ˜น lock์„ manually controlํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ
โ€ข If you have an application that requires very high performance but needs
transaction-like behavior only occasionally, it might be worth using a fast nontransaction-safe table type and using locks to solve your transaction issue.
โ€“ ๋˜ํ•œ LOCK TABLES์„ callํ•˜๋Š” ๊ฒฝ์šฐ
โ€ข MySQL's data file์— ์ง์ ‘ ์ž‘์—…ํ•˜๋Š” ๊ฒฝ์šฐ. ์˜ˆ: Backup ์‹œ ํ™•์ธ!: โ€œdisk files stayed
consistent and unmodified while backing up.โ€ ์ฆ‰, you would need to lock them.
โ€“ (์ค‘์š”) ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด lock์„ ์‚ฌ์šฉ ํ›„์—๋Š” ๊ฐ€๋Šฅํ•œ ๋นจ๋ฆฌ release lock. Some
tasks you may lock while performing, such as reindexing or backing up
large files, can take significant amounts of time.
116
InnoDB์˜ Transaction Model
โ€ข ACID Compliance
โ€“ Atomicity; transactions are atomic and indivisible.
โ€“ Consistency; operations transform the database from one valid state
to another. ์ฆ‰, no intermediate stages where the data is inconsistent.
โ€“ Isolation; transactions do not affect each other while they are running.
Each transaction should be able to view the world as though it is the
only one reading and altering things.
โ€ข ์‹ค์ œ์—์„œ๋Š” ์–ด๋ ค์šด ์ƒํ™ฉ์ด๋ฏ€๋กœ lock์„ ํ†ตํ•ด ์ด๋Ÿฌํ•œ illusion์„ ๋งŒ๋“ค์–ด ๋ƒ„.
โ€“ Database์™€ option์— ๋”ฐ๋ผ different levels of isolation.
โ€“ Durability; ์ผ๋‹จ transaction์ด commit๋˜๋ฉด ๊ทธ ํšจ๊ณผ(effect)๋Š” permanent
ํ•˜๋‹ค.
โ€ข ๋Œ€๊ฐœ ๋‹จ์ˆœํ•˜์ง€๋งŒ ๋ณต์žกํ•œ DBMS (locking ๋ฐ multiversioning์„ ํ†ตํ•ด concurrent
multiuser access๋ฅผ ๋ณด์žฅํ•˜๊ณ  caching์„ ํ†ตํ•ด ์„ฑ๋Šฅํ–ฅ์ƒ์„ ์ถ”๊ตฌ)๊ฒฝ์šฐ ์ž ์žฌ์  ํญํƒ„!
โ€ข ๋˜ํ•œ durability implies recoverability in the event of a failure ๏ƒ  we should
be able to combine a backup and a log to bring the database back to its
precrash state and perhaps process transactions that had been logged but
not yet executed or committed.
โ€“ InnoDB tables (or BerkeleyDB tables)์„ ์ด์šฉํ•˜๋ฉด
โ€ข MySQL is ACID compliant. (cf. MyISAM table์ด์šฉํ•˜๋Š” ๊ฒฝ์šฐ x)
โ€ข You can choose the level of isolation that transactions have from one
117
another. The binary log and repair tools provide durability.
โ€ข Transaction Isolation
โ€“ InnoDB table์€ 4๊ฐ€์ง€ transaction isolation level์„ ๊ฐ€์ง.
(โ€˜strong๏ƒ weakโ€™์ˆœ์„œ)
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
Serializable
Repeatable read
Read committed
Read uncommitted
/* trade-off between robustness and performance. */
โ€“ Serializable isolation
โ€ข is the ideal from a purity and robustness angle.
โ€ข ๏ƒ  Reads and writes on the database appear to be happening in a
sequence, with changes from a write being completely recorded before
the next read starts.
โ€ข Transaction์ด ํ•ญ์ƒ noninterleaved sequence๋กœ ์ˆ˜ํ–‰๋  ํ•„์š”๋Š” ์—†๋‹ค. (๋งŽ์€ ๊ฒฝ
์šฐ ์„œ๋กœ interfereํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ)
โ€ข ๊ทธ๋Ÿฌ๋‚˜ clash๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด noninterleaved sequence๋กœ ์ˆ˜ํ–‰ํ•ด์•ผ ํ•œ๋‹ค. ์ด ๊ฒฝ์šฐ
locking and waiting + (์–ด๋–ค transaction๋“ค์ด interfereํ•˜๋Š”์ง€์˜ ์กฐํ•ฉ์— ๋Œ€ํ•œ)
overhead of predicting ๏ƒจ serializable isolation ์€ ๊ฐ€์žฅ ์„ฑ๋Šฅ์ด ๋Š๋ ค์ง. ์ด๋Ÿฌ
ํ•œ mode ํ•„์š” ์‹œ ๋‹ค์Œ ๋ช…๋ น์–ด ์ˆ˜ํ–‰:
โ€ข /*set transaction isolation level serializable; */
โ€“ Repeatable read (์ดํ•˜ ๋‹ค์Œ ํŽ˜์ด์ง€)
โ€“ Read committed
โ€“ Read uncommitted
118
โ€“ repeatable read.
โ€ข InnoDB์—์„œ์˜ default level. ์—ฌ๊ธฐ์„œ๋Š” each transaction gets to work in an isolated
version of the table where each row remains as it was when the transaction
started. Reading a row is guaranteed to be repeatable.
โ€ข If you call select * from account where number=1; at the start of the
transaction and perform the same query later in the transaction, you will get the
same results both times. You can, however, get what are called phantom reads.
It is possible that another transaction which commits before yours is adding new
rows to the table. If you perform the same query with a condition twice, such as
select * from account where balance>1000;
โ€ข it is possible that you will get new rowsโ€”phantom rowsโ€”the second time. ์‹ค์ œ๋กœ
๋Š” phantom read๋Š” ๋งค์šฐ ๋“œ๋ฌผ๋‹ค. InnoDB์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ ํ•ด๊ฒฐ์— (์ด๋Ÿฌํ•œ ์กฐ๊ฑด์„ ์ ์šฉ
ํ•˜๋Š” column์ด index๋˜์—ˆ๋‹ค๋ฉด) next key locking ๋ผ๋Š” algorithm ์‚ฌ์šฉ.
โ€ข ๋˜ํ•œ InnoDB์˜ row-level locking. ๏ƒ  โ€ฆ As well as locking the rows used, next key
locking also locks the gaps between rows found in the index. Because phantom
reads are addressed in this way, few systems really need to be put in serialized
isolation mode.
โ€“ read committed
โ€ข your transactions are no longer very isolated. If you perform a query and repeat
it later in the same transaction, you will get different results the second time if
another transaction has modified the data in the meantime and committed.
โ€ข ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š”:
set transaction isolation level read committed;
โ€“ read uncommitted,
โ€ข ์—ฌ๊ธฐ์„œ๋Š” it is distinctly arguable not only that your transactions are no longer
isolated, consistent, and therefore ACID compliant, but that you no longer really
have transactions. In this mode, it is possible for transactions to read changes
that other transactions have made before the changes have been committed.
(=a dirty read). You would tolerate this only in fairly unusual circumstances, such
as at a time when you know all active threads will be reading or writing, but not
119
both. read uncommitted mode๋ฅผ ์œ„ํ•ด์„œ๋Š”:
set transaction isolation level read uncommitted;
Table 10.1. Transaction Isolation Level Characteristics
Dirty Read
Nonrepeatable Read
Phantom Read
Read Uncommitted
Possible
Possible
Possible
Read Committed
Not possible
Possible
Possible
Repeatable Read
Not possible
Not possible
Possible (but unlikely)
Serializable
Not possible
Not possible
Not possible
120
Part V: MySQL ๊ด€๋ฆฌ
11
12
13
14
15
16
Managing User Privileges
Configuring MySQL
Administering Your Database
Backup and Disaster Recovery
Securing Your MySQL Installation
Replicating Your Database
121
11. User Privileges์˜ ๊ด€๋ฆฌ
โ€ข Creating user accounts with GRANT and REVOKE
โ€ข Privilege levels
โ€ข Understanding the privilege tables
122
Creating User Accounts with GRANT and REVOKE
โ€ข
Granting Privileges
โ€“ to create user accounts and give users access to databases, tables, and functions.
grant usage
/* usage= log in๋งŒ ๊ฐ€๋Šฅ */
on *
to luke@localhost identified by 'password';
โ€“ ์ผ๋ฐ˜ํ˜•:
GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
ON {tbl_name | * | *.* | db_name.*}
TO user_name [IDENTIFIED BY [PASSWORD] 'password']
[, user_name [IDENTIFIED BY 'password'] ...]
[REQUIRE
NONE |
[{SSL| X509}]
[CIPHER cipher [AND]]
[ISSUER issuer [AND]]
[SUBJECT subject]]
[WITH [GRANT OPTION | MAX_QUERIES_PER_HOUR # |
MAX_UPDATES_PER_HOUR # |
MAX_CONNECTIONS_PER_HOUR #]]
โ€ข * ; ํ˜„์žฌ ์„ ํƒ๋œ database์— ์ ์šฉ, ์„ ํƒ๋œ database๊ฐ€ ์—†์„ ๋•Œ์—๋Š” =*.*
โ€ข TO ; ๋Œ€์ƒ์ž ์ง€์ •. Log in ๋œ host๋„ ๊ฐ€๋Šฅ ; ์˜ˆ: fred@localhost. โ€ฆ (Username; ์ตœ๋Œ€ 16 ๋ฌธ์ž)
โ€ข IDENTIFIED BY; password ์„ค์ • (์‹ ๊ทœ ์‚ฌ์šฉ์ž ๋˜๋Š” ๊ธฐ์กด user).
โ€ข ์‚ฌ์šฉ์ž๊ฐ€ Password ๋ณ€๊ฒฝ ์‹œ์— ; set password = password('newpassword');
โ€ข ๊ด€๋ฆฌ์ž๊ฐ€ ์‚ฌ์šฉ์ž password๋ณ€๊ฒฝ; set password for fred@localhost = password(โ€˜newpasswordโ€™)
/*๏ƒŸ mysql์ด๋ผ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— access๊ถŒํ•œ์„ ๊ฐ€์ ธ์•ผ ํ•จ */
โ€ข WITH GRANT OPTION ; a special privilege that allows the user to grant privileges.
โ€ข WITH ; 1์‹œ๊ฐ„ ๋‚ด์— ์‹œ๋„ํ•  ์ˆ˜ ์žˆ๋Š” query, update, connection ํšŒ์ˆ˜ (default= 0 =no limitation.)
โ€ข REQUIRE; secure connection์ด ์žˆ์–ด์•ผ ์‚ฌ์šฉ์ž๊ฐ€ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ. (ํ•ด๋‹น configuration123
ํ•„์š”)
Privilege Levels
Table 11.1 User-Level Privileges
Privilege
Meaning (์‚ฌ์šฉ์ž๊ฐ€ โ€ฆ์„ ํ•  ์ˆ˜ ์žˆ์Œ)
CREATE
Create tables
CREATE TEMPORARY TABLES
Create temporary tables
DELETE
Delete rows
EXECUTE
Execute procedures
INDEX
Create indexes
INSERT
Insert rows
LOCK TABLES
Lock tables
SELECT
Select rows
SHOW DATABASES
โ€˜SHOW DATABASESโ€™ ํ†ตํ•ด available DB list ์ถœ๋ ฅ
UPDATE
Update rows
USAGE
Users can log in, but cannot do anything else
124
Table 11.2 Administrator-Level Privileges
Privilege
Meaning
ALL
User has all the privileges except WITH GRANT OPTION
ALTER
User can alter tables. ์ผ๋ถ€ power user์—๊ฒŒ ๋ถ€์—ฌํ•  ๋•Œ๋„ ์ฃผ์˜ํ•  ๊ฒƒ
privilege table์„ ๋ณ€๊ฒฝํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜๋„ ์žˆ์Œ
DROP
User can drop tables. Only to the trusted users!
FILE
User can load data from a file. Only to the trusted users!
(์ฃผ์˜) ์‚ฌ์šฉ์ž๊ฐ€ arbitrary file (์˜ˆ:/etc/passwd)์„ loadํ•˜์ง€ ์•Š๋„๋ก ์œ ์˜
PROCESS
MySQL ์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ๋ชจ๋“  process์˜ list๋ฅผ ์ถœ๋ ฅ
RELOAD
User can use the FLUSH statement.
REPLICATION CLIENT
User can check where the masters and slaves are.
REPLICATION SLAVE
slave์—์„œ์˜ special replication user ๋ฅผ ์œ„ํ•œ ํŠน์ˆ˜ํ•œ privilege.
SHUTDOWN
User can run mysqladmin shutdown.
SUPER
User can connect even if MySQL has its maximum number of
connections and can execute the commands CHANGE MASTER, KILL
(thread), mysqladmin debug, PURGE MASTER LOGS, and SET
GLOBAL.
WITH GRANT OPTION
User can pass on any privileges he has.
REFERENCES
Future use๋ฅผ ์œ„ํ•ด ์˜ˆ์•ฝ๋จ
125
๏ƒŸ
Evaluating Privileges
โ€ข 4 sets of privileges are granted with GRANT
statement:
โ€“ Global privileges ; ๋ชจ๋“  database์— ์ ์šฉ.
grant all on *.* to fred;
โ€“ Database privileges ; ํŠน์ • database์— ์ ์šฉ.
grant all on employee.* to fred;
โ€“ Table privileges ; ํŠน์ • table์— ์ ์šฉ.
grant select on department to fred;
โ€“ Column privileges apply to a single column.
grant select (employeeID) on employee to fred;
โ€ข ํŠน์ • ์‚ฌ์šฉ์ž์˜ privilege ๊ฒฐ์ •์—๋Š”
โ€“ ๊ทธ ์‚ฌ์šฉ์ž์˜ <<global privileges + database privileges +
table privileges + column privileges>> ๋ฅผ ORed together.
126
Using the REVOKE Statement
โ€ข = GRANT์˜ ๋ฐ˜๋Œ€. (= privilege๋ฅผ ๋นผ์•—์Œ)
โ€“ ์˜ˆ: revoke all on employee.* from fred;
โ€ข ์ผ๋ฐ˜ํ˜•:
REVOKE
priv_type
[(column_list)]
[(column_list)] ...]
ON {tbl_name | * | *.* | db_name.*}
FROM user_name [, user_name ...]
[,
priv_type
127
Privilege Tables
โ€ข GRANT ๋ฐ REVOKE์˜ ๊ฒฐ๊ณผ๋Š” mysql์ด๋ผ๋Š” database
์— ์ €์žฅ. ์ด๋“ค ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉ ๋Œ€์‹  ์ง์ ‘ ์ด database๋ฅผ
์ˆ˜์ •๋„ ๊ฐ€๋Šฅ. ๋‹จ, ๋‹ค์Œ ๋ฌธ์žฅ์„ ์ˆ˜ํ–‰์‹œํ‚ฌ ๊ฒƒ.
flush privileges;
โ€ข six tables in the mysl database:
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
user
db
host
tables_priv
columns_priv
func
โ€“ ์ด ์ค‘ ์•ž์˜ 5๊ฐœ๊ฐ€ user privilege์™€ ๊ด€๊ณ„. (func ํ…Œ์ด๋ธ”์€ userdefined function information์„ ์ €์žฅ)
โ€ข ์•ž์˜ 3๊ฐœ tableโ€“ user, db, and hostโ€” ์€ database connection
์„ ํ—ˆ์šฉํ• ์ง€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š”๋ฐ ์ด์šฉ.
128
โ€ข Understanding the user Table
โ€“ ์‚ฌ์šฉ์ž์˜ global privilege set์— ๋Œ€ํ•œ ์ •๋ณด๋กœ์„œ user table์˜ column์€:
โ€ข Scope columns ; determine when a row is relevant.
โ€“ Host: Where the user is connecting from
โ€“ User: The username
โ€“ Password: The user's password, as encoded by the PASSWORD() function
โ€ข Privilege columns ; ๊ฐ๊ฐ ๋‹ค์Œ์˜ global privileges์— ํ•ด๋‹น. Y (๏ƒ user has the
global privilege) or N (๏ƒ  the user does not have global privilege)์˜ ๊ฐ’์„ ๊ฐ€์ง.
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
Select_priv
Update_priv
Index_priv
Create_priv
Grant_priv
Reload_priv
Process_priv
Show_db_priv
Create_tmp_table_priv
Execute_priv
Repl_client_priv
Insert_priv
Delete_priv
Alter_priv
Drop_priv
References_priv
Shutdown_priv
File_priv
Super_priv
Lock_tables_priv
Repl_slave_priv
โ€ข Secure connection columns ; grant๋ฌธ์—์„œ์˜ REQUIRE ์— ํ‘œ์‹œ.
โ€“ ssl_type
โ€“ x509_issuer
ssl_cypher
x509_subject
โ€ข Resource limitation columns ; ์‚ฌ์šฉ์ž resource limitation.
โ€“ max_questions
โ€“ max_connections
max_updates
129
โ€ข Understanding the db Table
โ€“ stores a user's privileges for particular databases.
โ€ข Scope columns ; determine when a row of privileges is relevant. If you have
different rules for different hosts, leave the host field blank and then create
a corresponding set of rows in the host table to give more information.
โ€“ Host
โ€“ User
Db
โ€ข Privilege columns ; specify whether the combination of Host, Db, and User
have each of the listed privileges. ์—ญ์‹œ Y or N ๊ฐ’์„ ๊ฐ€์ง.
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
Select_priv
Insert_priv
Update_priv
Delete_priv
Index_priv
Alter_priv
Create_priv
Drop_priv
Grant_priv
Create_tmp_table_priv
Lock_tables_priv
โ€ข Understanding the host Table
โ€“ MySQL consults the host table when it finds a blank host entry in the
db table. (๋‹จ, GRANT ๋ฌธ์œผ๋กœ๋Š” ํšจ๊ณผ๊ฐ€ ์—†๊ณ  ๋Œ€์‹  manually set upํ•  ๊ฒƒ)
โ€ข
Scope columns ; determine when a row of privileges is relevant. Each row
here gives information for a single database accessed from a single host.
โ€“ Host
Db
โ€ข Privilege columns ; specify whether the combination of Host and Db have
each of the listed privileges. ; contain values Y or N. ๋‹จ, ํ•ด๋‹น columns:
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
Select_priv
Update_priv
Index_priv
Create_priv
Grant_priv
Lock_tables_priv
Insert_priv
Delete_priv
Alter_priv
Drop_priv
Create_tmp_table_priv
130
โ€ข Understanding the tables_priv Table
โ€“ ๊ฐœ๋ณ„ table์— ๋Œ€ํ•œ user privilege๋ฅผ ํ‘œํ˜„.
โ€ข Scope columns ; (์•ž์˜ ์„ค๋ช… ์ฐธ์กฐ) + Table_name privilege (; lists the
specific table that a grant applies to)
โ€“ Host
โ€“ User
Db
Table_name
โ€ข Grant columns ; ์ด privilege ๋ฅผ ๋ˆ„๊ฐ€, ์–ธ์ œ grantํ–ˆ๋Š”์ง€์— ๋Œ€ํ•œ ์ •๋ณด.
โ€“ Grantor
Timestamp
โ€ข Table_priv column ; determines what privileges the Host/Db/User has
on the table listed in Table_name.
โ€“ ๊ฐ’: Select, Insert, Update, Delete, Create, Drop, Grant, References, Index,
Alter.
โ€ข Column_priv column ; table ๋‚ด ๋ชจ๋“  column์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž์˜ privilege๋ฅผ
์•Œ๋ ค ์คŒ.
โ€“ ์ˆ˜๋ก ๊ฐ’: Select, Insert, Update, and References.
131
โ€ข Understanding the columns_priv Table
โ€“ ๊ฐœ๋ณ„ column์— ๋Œ€ํ•œ user privilege๋ฅผ ํ‘œํ˜„. ๋‹ค์Œ column ์ˆ˜๋ก:
โ€ข Scope columns ; determine when a row in this table is relevant.
โ€“
โ€“
โ€“
โ€“
โ€“
Host
Db
User
Table_name
Column_name
โ€“
โ€“
โ€“
โ€“
Select
Insert
Update
References.
โ€ข Column_priv column ; determines which privileges have been
granted to the combination outlined by the scope column.
โ€ข Timestamp column ; tells when this privilege was granted.
132
12. Configuring MySQL
โ€ข Setting MySQL configuration options
โ€ข Multi-install configuration options
โ€ข Configuring for internationalization
133
Setting MySQL Configuration Options
โ€ข MySQL programs have configuration options.
โ€“ (๏ƒŸ command line or) options file (ํ•˜๋‚˜์˜ file์„ ํ†ตํ•ด ์—ฌ๋Ÿฌ MySQL ํ”„๋กœ
๊ทธ๋žจ์— default option ์ง€์ •) Specifically;
โ€ข mysql, mysqladmin, mysqld, mysqld_safe, mysql.server, mysqldump,
mysqlimport, mysqlshow, mysqlcheck, myisamchk, and myisampack.
โ€“ ์žฅ์ :
โ€ข ํ‘œ์ค€ options๋ฅผ ์šด์˜๏ƒ  ์—ฌ๋Ÿฌ ์„œ๋ฒ„ ์šด์˜ ์‹œ์— ํŽธ๋ฆฌ. (ํŠนํžˆ replication ์ด์šฉ ์‹œ)
โ€ข Under Unix, MySQL also supports the use of:
โ€“ Per-server
» = An options files for the each whole server (๋‹จ, ํ•˜๋‚˜์˜ ํ•˜๋“œ์›จ์–ด์—์„œ ์—ฌ๋Ÿฌ
๊ฐœ์˜ MySQL server ์šด์˜๊ฐ€๋Šฅ)
» a global options file (=ํ•˜๋‚˜์˜ ๊ธฐ๊ณ„ ์ƒ์˜ ๊ฐ๊ฐ์˜ MySQL server์— ๋Œ€ํ•œ options
file) ; /etc/my.cnf์— ์œ„์น˜
» Per-server files are in in the data directory for each server.
โ€“ Per each individual users.
» ์œ„์น˜: ๊ฐ ์‚ฌ์šฉ์ž์˜ home directory.
» per-user file์€ prefixed with a dot (์˜ˆ: .my.cnf instead of my.cnf)
โ€ข Windows์—์„œ๋Š” you have a choice of:
โ€“ Windows ๋””๋ ‰ํ† ๋ฆฌ์— my.ini or
โ€“ ์„œ๋ฒ„๊ฐ€ ์„ค์น˜๋œ ๋“œ๋ผ์ด๋ธŒ์˜ root ๋””๋ ‰ํ† ๋ฆฌ์— ๋‘๊ณ  (์˜ˆ: C:\) my.cnf
โ€“ = a global options file๏ƒ  ์ฆ‰ ์„œ๋ฒ„์ƒ์˜ ๋ชจ๋“  ์‚ฌ์šฉ์ž์— ์ ์šฉ.
134
Listing 12.1 Sample my.cnf File
[mysqld]
# turn on binary logging and slow query logging
log-bin
log-slow-queries
# InnoDB config
# This is the basic config as suggested in the manual
# Datafile(s) must be able to hold your data and indexes.
# Make sure you have enough free disk space.
innodb_data_file_path = ibdata1:10M:autoextend
#
# Set buffer pool size to 50 - 80 % of your computer's
memory
set-variable = innodb_buffer_pool_size=70M
set-variable = innodb_additional_mem_pool_size=10M
#
# Set the log file size to about 25 % of the buffer pool
size
set-variable = innodb_log_file_size=20M
set-variable = innodb_log_buffer_size=8M
#
# Set ..flush_log_at_trx_commit to 0 if you can afford
losing
# some last transactions
innodb_flush_log_at_trx_commit=1
์œคํ˜•๊ธฐ:
[mysqld]
์ ์šฉ์‹œํ‚ค๊ณ ์ž ํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ ์ง€์ •. ๋˜ํ•œ [client]๋ฅผ ํ†ตํ•ด ๋ชจ๋“ 
client program์— ์ ์šฉ์‹œํ‚ค๋„๋ก ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.
<3 forms of syntax for setting individual options: >
(I) Specifying the option you want switched on; ์˜ˆ:
log-bin == mysqld --log-bin.
(ii) Specifying the option you want with a value; ์˜ˆ:
innodb_flush_log_at_trx_commit=1
(iii) Specifying the option you want with a value
using the set-variable syntax; ์˜ˆ:
set-variable = innodb_log_buffer_size=8M
/* (iii)syntax๋Š” deprecated, but ์•Œ์•„๋‘˜ ๊ฒƒ. */์˜ˆ์ œํŒŒ์ผ
(my.cnf)์€ ๋งค๋‰ด์–ผ์ƒ์˜ InnoDB configuration์˜ˆ์ œ */
Certain options work for all these programs:
·
--no-defaults ; no options files are to be read.
·
--print-defaults ; tell you what the values of all
the options are being set to for this program.
·
--defaults-file=/path/to/file ; tell the program
to use the specified file instead of any other options
files it has. configuration ๋ณ€๊ฒฝ์„ testํ•  ๋•Œ ํŽธ๋ฆฌ.
·
--defaults-extra-file=/path/to/file will read
the specified file after reading the global options file
but before reading any individual user options files.
๋‹ค๋ฅธ ๊ณณ์—์„œ๋„ ๋Œ€๋ถ€๋ถ„ ์–ธ๊ธ‰๋จ. ๋‹จ, mysqld์— ๋Œ€ํ•ด์„œ๋Š” ์ดํ•˜ ์„ค๋ช….
135
โ€ข Setting Options for mysqld
โ€ข mysqld --help
โ€“ ์ฃผ์š” options:
โ€ข ansi:
โ€“ ANSI ํ˜ธํ™˜ mode๋กœ ์ˆ˜ํ–‰. ๏ƒ  MySQL์—์„œ ANSI-99 SQL ์‚ฌ์šฉ ๊ฐ€๋Šฅ.
โ€ข basedir:
โ€“ ๋‚˜๋ฆ„๋Œ€๋กœ์˜ ์„ค์น˜ base directory ์„ค์ •.
โ€ข datadir:
โ€“ basedir,์™€ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ์— ๋Œ€ํ•ด ์ ์šฉ
โ€ข log-bin:
โ€“ Turn on binary logging. (log์˜ ์œ„์น˜/file๋ช… ์ง€์ • ๊ฐ€๋Šฅ)
โ€ข log-error:
โ€“ Turn on error logging. Again, you can specify the location of the log.
โ€ข log-slow-queries:
โ€“ Turn on slow query logging.
โ€ข port:
โ€“ Specify the port that the server should listen on. Default๋Š” 3306.
โ€ข user:
โ€“ Specify the user that the MySQL server should run as.
136
Setting InnoDB Configuration Options
โ€ข
Option์ง€์ • ์—†์ด InnoDB๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ option์ง€์ • ์‹œ ์„ฑ๋Šฅ๊ฐœ์„ 
โ€“ innodb_data_file_path = ibdata1:10M:autoextend
โ€ข InnoDB data๋ฅผ ๋ณด๊ด€ํ•  ์žฅ์†Œ ์ง€์ •. MyISAM table (; table๋ณ„๋กœ ๋ณ„๋„ file)๊ณผ ๋‹ฌ๋ฆฌ, InnoDB tables
are stored in a shared tablespace, which may consist of one or more files.
โ€ข (์ด ์˜ˆ์—์„œ๋Š”) ๋ชจ๋“  InnoDB data๋ฅผ ibdata1๋ผ๋Š” ํ•˜๋‚˜์˜ ํŒŒ์ผ์— ๋ณด๊ด€, initial file size=10MB, and
to automatically make it bigger (8MB at a time) if the tablespace becomes full.
โ€ข (์ผ๋ฐ˜ํ˜•) filename:filesize[;filename:filesize;...][:autoextend[:max:size]]
โ€ข The autoextend option allows the tablespace to grow. max option ; max size ์ง€์ •.
โ€“ innodb_buffer_pool_size=70M
โ€ข buffer size์ง€์ • (table data์™€ index๋ฅผ cache). Cache์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ํด ์ˆ˜๋ก disk I/O๋Š” ์ค„์–ด๋“ ๋‹ค.
โ€ข ์ง€์ •๋˜๋Š” buffer pool์˜ ํฌ๊ธฐ๋Š” ์„œ๋ฒ„ ์ƒ์˜ ๋‹ค๋ฅธ application ์œ ๋ฌด, ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ ๋“ฑ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง.
โ€“ innodb_additional_mem_pool_size=10M
โ€ข sets aside memory to store internal MySQL data structures. If MySQL is running out of
room here, it will begin writing warnings to the error log.
โ€“ innodb_log_file_size=20M
โ€ข sets the size of each log file. InnoDB rotates between n log filesโ€”where n is the value set
in the innodb_log_files_in_group option, which defaults to 2, the recommended value.
โ€“ innodb_log_buffer_size=8M
โ€ข ; sets the size of the buffer in which logs are stored before they are written to disk.
โ€“ innodb_flush_log_at_trx_commit=1
โ€ข
โ€ข
โ€ข
โ€ข
1 ๋กœ ์ง€์ • = transaction์ด commit๋  ๋•Œ๋งˆ๋‹ค log will be flushed to disk. (๊ฐ€์žฅ ์ผ๋ฐ˜์  ํ˜•ํƒœ)
0์œผ๋กœ ์ง€์ • ์‹œ; the log will be written to and flushed to disk only roughly once per second.
2๋กœ ์ง€์ • ์‹œ; the log will be written to with each commit, but flushed only once per second.
Values of 0 or 2 will improve performance, but are obviously a fairly risky proposition.
137
Multi-Install Configuration Options
โ€ข
โ€ข
โ€ข
โ€ข
ํ•˜๋‚˜์˜ ํ•˜๋“œ์›จ์–ด์—์„œ ์—ฌ๋Ÿฌ ๊ฐœ์˜ MySQL ์„œ๋ฒ„ ์ˆ˜ํ–‰ (์˜ˆ: ISP users, ๊ต์œก)
โ€“ port: Each server must listen on a different port.
โ€“ socket: Under Unix, each server must use a different socket file. Under Windows, the
socket option sets the name of the named pipe used by the server. In both cases,
this value for socket must be different for each server.
โ€“ shared-memory-base-name (Windows only): ๊ฐ ์„œ๋ฒ„๋Š” ์„œ๋กœ ๋‹ค๋ฅธ shared memory ์‚ฌ์šฉ.
โ€“ pid-file (Unix only): ๊ฐ ์„œ๋ฒ„๋Š” process id (pid)๋ฅผ ๊ธฐ๋กํ•  ์„œ๋กœ ๋‹ค๋ฅธ ํŒŒ์ผ์„ ํ•„์š”๋กœ ํ•จ.
โ€“ Logging options: If you set any of the log file options, such as log-bin, you will need
to set up different log file locations for each server.
(๊ฐ„ํŽธ๋ฒ•) ์„œ๋ฒ„๋งˆ๋‹ค basedir option์„ ๋‹ค๋ฅด๊ฒŒ ์„ค์ • ๏ƒ  force the data directories and
log files to be different. (๊ถŒ๊ณ ) ์„œ๋ฒ„๋งˆ๋‹ค ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋ณ„๋„๋กœ ์„ค์ •.
--defaults-file option ์˜ ์œ ์šฉ์„ฑ = starting each server instance with a different
set of defaults (or for installing each server as a Windows service with a
separate set of defaults).
(์ฐธ์กฐ) ์—ฌ๋Ÿฌ ๊ฐœ์˜ (multiple) ์„œ๋ฒ„๋ฅผ ์ˆ˜ํ–‰ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ ํ”„๋กœ๊ทธ๋žจ, ๊ธฐํƒ€ (์˜ˆ:
mysqladmin ๋“ฑ)์—๊ฒŒ ์–ด๋Š ์„œ๋ฒ„์— ์—ฐ๊ฒฐํ• ์ง€๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค.
โ€“ --port command switch
โ€“ ์ด ๊ฒฝ์šฐ, ์‚ฌ์šฉ์ž ๋ณ„ my.conf ๋ฅผ ํ†ตํ•ด ์ง€์ •ํ•˜๋ฉด ํŽธ๋ฆฌ (๏ƒ  ์‚ฌ์šฉ์ž๋ณ„๋กœ ์ž์‹ ์˜ ์„œ๋ฒ„์— ์ž๋™ ์—ฐ๊ฒฐ)
138
Configuring for Internationalization
โ€ข ๋‹ค์Œ 2๊ฐœ์˜ options to mysqld ์„ ํ†ตํ•ด default character set๊ณผ
collation ์„ค์ •.
โ€“ character set = the set of symbols used by default on the server.
โ€“ collation = the set of rules for performing comparisons, (sort
orderโ€”in the character set)
โ€ข --default-character-set option. Each character set has an
associated default collation,
โ€ข --default-collation option. If the combination of default
character set and default collation is not valid, mysqld will
give you an error message.
โ€ข Default:
โ€“ default character set = latin1,
โ€“ default collation = latin1_swedish_ci.
โ€ข This character set can also be described as ISO-8859-1 West European,
which is the one used in this book. The collation represents the sort
order for latin1 used by the Swedes and Finns.
โ€ข There are also collations for latin1 that represent the ways that
Germans, Danes, and Norwegians sort strings.
139
13. Administering Your Database
โ€ข Mysqladmin script ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ์‚ดํŽด๋ด„.
๋˜ํ•œ
โ€ข mysqlshow scripts
โ€ข mysqlcheck scripts
โ€ข ๋ช…๋ น์–ด:
โ€“ KILL, RESET, CHECK, REPAIR, and
โ€“ ANALYZE TABLE
140
Starting Up and Shutting Down
the MySQL Server
โ€ข Under Linux
โ€“ start the server with
โ€ข /etc/init.d/mysqld start
โ€ข ๋‹จ, path์ง€์ • ์œ ์˜.
โ€“ You can also start the server by running
โ€ข safe_mysqld
โ€“ To shut down your MySQL server
โ€ข /etc/init.d/mysqld stop or
โ€ข mysqladmin -u root -p shutdown
โ€ข root ๋ฐ privilege๋ถ€์—ฌ์‹œ ์กฐ์‹ฌ.
โ€“ Figure 13.1. Services window in Windows Admin Tools (์ƒ๋žต)
โ€“ mysqladmin script for Linux๋ฅผ ์ด์šฉํ•ด์„œ shutdown๋„ ๊ฐ€๋Šฅ
141
Server ๋ฐ Database์— ๋Œ€ํ•œ ์ •๋ณด์˜ ํš๋“
โ€ข Retrieving Database Information
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
mysqlshow /* DB ์ •๋ณด์ œ๊ณต. ๋‹จ, Parameter๊ฐ€ ์—†์œผ๋ฉด access๊ฐ€๋Šฅํ•œ ๋ชจ๋“  DB*/
= show databases; /*mysql monitor ๋˜๋Š” ๋‹ค๋ฅธ UI์—์„œ ์ˆ˜ํ–‰*/
mysqlshow -u username -p password ๋„ ๊ฐ€๋Šฅ
mysqlshow ?help /* ๏ƒ  a full list of these options.*/
mysqlshow -u username -p database /*ํŠน์ • DB์— ๋Œ€ํ•œ ์ •๋ณด (list of table)*/
mysqlshow -u username --status employee
โ€“ /* ๏ƒ  information about the storage engine used in each table, how much data is
in each table, the current value of any auto-increment column in a table, and
the character set used in each table. */
โ€“ MySQL client๋‚ด์—์„œ SHOW ๋ช…๋ น์–ด ๏ƒ  database ๋ฐ ์„œ๋ฒ„ ์ƒํƒœ ์ •๋ณด.
โ€ข
โ€ข
โ€ข
โ€ข
show
show
show
show
databases; and
tables; /* ๏ƒ  databases and table์— ๋Œ€ํ•œ ์ •๋ณด. ๋‹จ, options ์ด ๋งŽ์Œ */
columns from tablename; /* ๏ƒ  DESC statement.์—์„œ์™€ ๊ฐ™์€ ์ •๋ณด */
table status /* mysqlshow โ€“status์™€ ๊ฐ™์€ ์ •๋ณด */
142
โ€ข Viewing Server Status and Variables
โ€ข SHOW STATUS /* inside MySQL, or */
โ€ข mysqladmin -u username -p -extended-status /* command line์—์„œ*/
โ€ข ๏ƒจ ์„œ๋ฒ„ ์‹คํ–‰ ์ดํ›„์˜ ํ†ต๊ณ„/์ •๋ณด. ์˜ˆ:
โ€“ com_select ; tells you how many select statements have been executed
โ€“ threads_connected: = current number of connections to the server.
โ€“ slow_queries: = number of queries this server has run that have taken more
time than the value of the server variable long_query_time. These queries
are logged in the Slow Query Log.
โ€“ uptime: This is how long this server instance has been running in seconds.
โ€“ To see the values of server variables, you can use
โ€ข show variables; /*from inside MySQL or */
โ€ข mysqladmin -u username -p variables /*from the command line */
โ€ข Viewing Process Information
โ€ข show processlist;
โ€ข mysqladmin -u username -p showprocesslist
143
โ€ข Viewing Grant and Privilege Information
show grants for username@host; ์˜ˆ:
mysql> show grants for root@localhost; ๏ƒจ
+-------------------------------------------------------------------------------------------+
| Grants for root@localhost
|
+-------------------------------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
|
+-------------------------------------------------------------------------------------------+
1 row in set (0.40 sec)
โ€“ To remind yourself what the various privileges are:
โ€ข show privileges;
โ€ข Viewing Reference Information About Tables
โ€ข show table types;
โ€ข show create table tablename; /* ์˜ˆ: */
show create table department; ๏ƒจ
CREATE TABLE 'department' (
'departmentID' int(11) NOT NULL auto_increment,
'name' varchar(30) default NULL,
PRIMARY KEY ('departmentID')
) TYPE=InnoDB CHARSET=latin1
โ€ข (์ฐธ๊ณ : column names are quoted to be safe, and the default character
setโ€”which we didn't specifyโ€”as specified here.)
144
โ€ข Setting Variables
โ€ข set variable=value; ์˜ˆ:
โ€ข set sql_safe_updates=1; /*๏ƒ turn on safe updates (=-i-am-a-dummy).
โ€ข Killing Threads
โ€“ โ€ฆ
โ€ข kill process_id;
โ€ข Clearing Caches
โ€“ ์˜ˆ: update user privilege by manually altering grant tables
๏ƒ  ์ด๋“ค ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด roll through the system ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒฝ์šฐ:
โ€ข flush privileges;
โ€ข flush query cache;
โ€ข /* ๏ƒ  defragment the query cache๏ƒ  performance๊ฐœ์„ .*/
โ€“ ๋˜๋Š”
โ€ข reset query cache;
โ€ข /*๏ƒ query cache๋ฅผ defragmentํ•˜๋Š” ๋Œ€์‹ , ์‹ค์ œ๋กœ clear it altogether.*/
145
Understanding the Log Files
โ€ข Logging ํ•„์š” ์‹œ์—๋Š” ์ด๋ฅผ switch on์‹œํ‚ฌ ๊ฒƒ. (set ๋ช…๋ น์–ด)
โ€“ Error log:
โ€ข ๋ฐœ์ƒ๋œ ๋ชจ๋“  error๋ฅผ ์ถ”์  (track). -- logged by default and appear in your data
directory.
โ€ข (ํŒŒ์ผ๋ช…: hostname.err (Linux) and mysql.err (Windows).) ์œ„์น˜๋ฅผ ๋ณ„๋„๋กœ ์ง€์ • ๊ฐ€๋Šฅ.
option log-error=filename (in my.ini or my.cnf file.)
โ€“ Query log:
โ€ข ์ˆ˜ํ–‰๋˜๋Š” ๋ชจ๋“  query๋ฅผ log. You can turn on this log and specify the location with the
option log=filename.
โ€“ Binary log:
โ€ข ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝ์‹œํ‚ค๋Š” ๋ชจ๋“  query๋ฅผ log. (๊ธฐ์กด update log๋ฅผ ๋Œ€์ฒด.) version 5.0 ์ดํ›„ ์—†์–ด์งˆ
๊ฒƒ. โ€“turn on/ ์œ„์น˜ ์ง€์ • by the option log-bin=filename.
โ€“ Slow query log:
โ€ข long_query_time๋ณ€์ˆ˜์— ์ €์žฅ๋œ ๊ฐ’๋ณด๋‹ค ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋Š” ๋ชจ๋“  query๋ฅผ log. -- turn on/์œ„์น˜ ์ง€
์ • by the option log-slow-queries=filename
โ€ข ์ด๋“ค์€ (binary log์„ ์ œ์™ธํ•˜๊ณ ) ๋ชจ๋‘ text files. ๏ƒŸ mysqlbinlog logfile ๋ช…๋ น
์–ด๋กœ ๋ณผ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ํฌ๊ธฐ๊ฐ€ ๊ณ„์† ๋Š˜์–ด๋‚˜๋ฏ€๋กœ regularly rotate your log files!
โ€“ Linux์˜ ๊ฒฝ์šฐ
โ€ข mysql-log-rotate script file์ด์šฉ
โ€“ LX ์ด์™ธ์˜ ๊ฒฝ์šฐ
โ€ข move the old log files to a safe location manually and then tell MySQL to start using
a new log file with the command
146
โ€ข mysqladmin flush-logs
mysqladmin Option Summary
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
mysqladmin
mysqladmin
mysqladmin
mysqladmin
mysqladmin
mysqladmin
mysqladmin
mysqladmin
mysqladmin
create databasename
drop databasename
ping
version
status
extended-status
processlist
kill id1,id2,id3...
variables
147
14. Backup ๋ฐ Disaster
Recovery
148
Backing Up and Restoring Your Database
โ€ข ์ผ๋ฐ˜๋ก 
โ€“ 4 ways you can make a backup in MySQL:
โ€ข mysqldump script ; creates a dump file, that is, a file containing
the SQL statements necessary to re-create the database.
โ€ข mysqlhotcopy script ; creates a data file. This copies the data files
for a particular database directly.
โ€ข ๋ฐ์ดํ„ฐ ํŒŒ์ผ์„ ์ง์ ‘ ๋ฐฑ์—…
โ€“ mysqlhotcopy ๊ฐ€ ํ•˜๋Š” ์ผ์„ ์ˆ˜์ž‘์—…์œผ๋กœ ํ•˜๋Š” ๊ฒƒ. ๋‹จ, ์ด๋•Œ copy์ „์— ํ•ด๋‹น
database๋ฅผ shut down ๋˜๋Š” ๋ชจ๋“  table์„ flush and lock (internal
consistency๋ฅผ ์œ„ํ•ด์„œ).
โ€“ Both mysqldump and mysqlhotcopy will flush and lock for you, so they
are easier, safer options.
โ€ข BACKUP TABLE and RESTORE TABLE ๋ช…๋ น์–ด;
โ€“ ์ฐธ๊ณ :
โ€ข ๋ชจ๋“  backup์—๋Š” ์ž‘์—… ๋™์•ˆ ์‚ฌ์šฉ์ž access ์ œํ•œ ๏ƒŸ To take a
consistent snapshot of a database, tables need to be flushed and
held constant while the backup is performed. ์ฆ‰, ์„œ๋ฒ„๋ฅผ ์ •์ง€์‹œํ‚ค๊ฑฐ
๋‚˜ ๋˜๋Š” table์„ lock.
โ€ข ํ•˜๋‚˜์˜ ํ•ด๊ฒฐ์ฑ… = replication. You can take down one slave and back
it up while users continue blissfully about their business.
149
โ€ข Backing Up and Restoring with mysqldump
โ€“ MySQL server๋ฅผ ์ ‘์†ํ•˜๊ณ  SQL dump file ์ƒ์„ฑ ( ๏ƒŸ dump file์—๋Š” DB
re-create์œ„ํ•œ SQL ๋ฌธ์žฅ์ด ์ˆ˜๋ก๋˜์–ด ์žˆ์Œ) ์˜ˆ:
โ€ข mysqldump --opt -u username -p password employee > backup.sql
โ€“ ์—ฌ๊ธฐ์„œ: --opt option; encapsulates a few other options
โ€“ Using this script on the simple employee database ๏ƒจ Listing 14.1.
Listing 14.1 Sample Output from mysqldump
-- MySQL dump 10.2
--- Host: localhost Database: employee
----------------------------------------------------------Server version 4.1.0-alpha-max-debug
--- Table structure for table 'assignmentโ€˜
-DROP TABLE IF EXISTS assignment;
CREATE TABLE assignment (
clientID int(11) NOT NULL default '0',
employeeID int(11) NOT NULL default '0',
workdate date NOT NULL default '0000-00-00',
hours float default NULL,
PRIMARY KEY (clientID,employeeID,workdate)
) TYPE=InnoDB CHARSET=latin1;
150
--- Dumping data for table 'assignmentโ€˜
-/*!40000 ALTER TABLE assignment DISABLE KEYS */;
LOCK TABLES assignment WRITE;
INSERT INTO assignment VALUES (1,7513,'0000-00-00',5),(1,7513,'200301-20',8.5);
UNLOCK TABLES;
/*!40000 ALTER TABLE assignment ENABLE KEYS */;
--- Table structure for table 'clientโ€˜
--
DROP TABLE IF EXISTS client;
CREATE TABLE client (
clientID int(11) NOT NULL auto_increment,
name varchar(40) default NULL,
address varchar(100) default NULL,
contactPerson varchar(80) default NULL,
contactNumber varchar(12) default NULL,
PRIMARY KEY (clientID)
) TYPE=InnoDB CHARSET=latin1;
--- Dumping data for table 'clientโ€˜
--
151
/*!40000 ALTER TABLE client DISABLE KEYS */;
LOCK TABLES client WRITE;
INSERT INTO clientVALUES (1,'Telco Inc','1 Collins St Melbourne','Fred
Smith','95551234'), (2,'The Bank','100 Bourke St Melbourne','Jan Tristan','95559876');
UNLOCK TABLES;
/*!40000 ALTER TABLE client ENABLE KEYS */;
--- Table structure for table 'departmentโ€˜
-DROP TABLE IF EXISTS department;
CREATE TABLE department (
departmentID int(11) NOT NULL auto_increment,
name varchar(30) default NULL,
PRIMARY KEY (departmentID)
) TYPE=InnoDB CHARSET=latin1;
--- Dumping data for table 'departmentโ€˜
-/*!40000 ALTER TABLE department DISABLE KEYS */;
LOCK TABLES department WRITE;
INSERT INTO department
VALUES
(42,'Finance'),
(128,'Research and Development'),
(129,'Human Resources'),
(130,'Marketing'),
(131,'Property Services');
UNLOCK TABLES;
152
/*!40000 ALTER TABLE department ENABLE KEYS */;
--- Table structure for table 'employeeโ€˜
-DROP TABLE IF EXISTS employee;
CREATE TABLE employee (
employeeID int(11) NOT NULL auto_increment,
name varchar(80) default NULL,
job varchar(30) default NULL,
departmentID int(11) NOT NULL default '0',
PRIMARY KEY (employeeID)
) TYPE=InnoDB CHARSET=latin1;
--- Dumping data for table 'employeeโ€˜
-/*!40000 ALTER TABLE employee DISABLE KEYS */;
LOCK TABLES employee WRITE;
INSERT INTO employee
VALUES
(6651,'Ajay Patel','Programmer',128),
(7513,'Nora Edwards','Programmer',128),
(9006,'Candy Burnett','Systems Administrator',128),
(9842,'Ben Smith','DBA',42),
(9843,'Fred Smith','DBA',131);
UNLOCK TABLES;
153
/*!40000 ALTER TABLE employee ENABLE KEYS */;
--- Table structure for table 'employeeSkillsโ€˜
-DROP TABLE IF EXISTS employeeSkills;
CREATE TABLE employeeSkills (
employeeID int(11) NOT NULL default '0',
skill varchar(15) NOT NULL default '',
PRIMARY KEY (employeeID,skill)
) TYPE=InnoDB CHARSET=latin1;
--- Dumping data for table 'employeeSkillsโ€˜
-/*!40000 ALTER TABLE employeeSkills DISABLE KEYS */;
LOCK TABLES employeeSkills WRITE;
INSERT INTO employeeSkills
VALUES
(6651,'Java'),
(6651,'VB'),
(7513,'C'),
(7513,'Java'),
(7513,'Perl'),
(9006,'Linux'),
(9006,'NT'),
(9842,'DB2');
UNLOCK TABLES;
/*!40000 ALTER TABLE employeeSkills ENABLE KEYS */;
154
โ€ข We could reload or re-create the employee database elsewhere by:
1. ์ ์ ˆํ•œ ์ด๋ฆ„์˜ DB๋ฅผ ์ƒ์„ฑํ•œ ํ›„
2. Loading this file using: mysql -u username -p < backup.sql
โ€ข mysqldump script์˜ options;
โ€ข --quick: tells MySQL to dump the data directly to the file, rather than
buffering it in memory first (default). This will speed things up.
โ€ข --add-drop-table: Tells MySQL to add a DROP TABLE statement before each
CREATE TABLE in the dump.
โ€ข --add-locks: Adds the LOCK TABLES and UNLOCK TABLES statements
โ€ข --extended-insert: use the multiline insert syntax to insert multiple rows
with a single INSERT. ์•ž์˜ ์˜ˆ์—์„œ:
INSERT INTO employeeSkills
VALUES
(6651,'Java'),
(6651,'VB'),
(7513,'C'),
โ€ข /* If we have to use our backup to re-create the database, this will be
faster to execute than a series of single INSERT statements. */
โ€ข --lock-tables: lock all the tables before starting to dump.
โ€“ (์ฃผ์˜) --opt (meaning optimized) optimizes the length of time it takes
to reload the dump file, rather than the length of time it takes to
create the dump file ๏ƒ  Creating the dump file can be slow.
155
โ€ข Here are a couple of other useful options:
โ€“
โ€“
โ€“
โ€“
--databases: list more than one database for dumping.
--all-databases: dump all the databases it has in storage.
--allow-keywords: MySQL keyword๋ฅผ column์ด๋ฆ„์œผ๋กœ ์‚ฌ์šฉ ์‹œ ์ง€์ •
-d or --no-data: Dumps only the database structure, not the
contents. ์—ฌ๋Ÿฌ ์„œ๋ฒ„์— DBํ…Œ์ŠคํŠธ ๋˜๋Š” deploy์‹œ ์œ ์šฉ.
โ€ข ์žฅ๋‹จ์ 
โ€“ ์žฅ์ : simple to use and it takes care of table locking issues for you.
โ€“ ๋‹จ์ :
โ€ข this script locks tables: Table ํฌ๊ธฐ์— ๋”ฐ๋ผ ์ˆ˜ ์ดˆ, ์ˆ˜ ๋ถ„.. ๋”ฐ๋ผ์„œ nonpeaktime์— ์ˆ˜ํ–‰.
โ€ข Because mysqldump works through the MySQL server, it will be slower
to run than mysqlhotcopy.
โ€ข mysqlhotcopy ๋Š” MySQL server ์ž์ฒด๋Š” ๋ณ„๋กœ ์ด์šฉ์น˜ ์•Š๊ณ  ์ง์ ‘ ํŒŒ์ผ ์‹œ์Šคํ…œ
์ด์šฉ.
156
โ€ข Backing Up and Restoring with mysqlhotcopy
โ€“ mysqlhotcopy
โ€ข (ํŠน์ง•) copies the actual database data files, rather than retrieving
data through a connection to the server.
โ€ข ์ฆ‰, DB table์„ flush ๋ฐ lockํ•˜๊ธฐ ์œ„ํ•ด DB์„œ๋ฒ„์— connection์„ ์„ค์ •ํ•˜์ง€๋งŒ
์ฃผ๋กœ ํŒŒ์ผ์‹œ์Šคํ…œ ์ค‘์‹ฌ์ด๋ฏ€๋กœ mysqldump๋ณด๋‹ค ๋‹ค์†Œ ๋น ๋ฅด๋‹ค.
โ€“ ์‚ฌ์šฉ:
โ€ข mysqlhotcopy -u username -p database_name backup_location
โ€ข Perl script์ด๋ฏ€๋กœ (Ux/Lx์—์„œ๋Š” ์ƒ๊ด€์—†์œผ๋‚˜) Windows์—์„œ๋Š” download
Perl for Windows www.activestate.com/Products/ActivePerl
โ€“ The files produced by mysqlhotcopy are replicas of the database
data files. To use these backups, you should stop the MySQL
server and replace the data files in the MySQL data directory
with the backed-up files.
157
โ€ข Backing Up and Restoring Manually
โ€“ = flush and lock the tables and copy the data files to a backup
location while the tables are still locked.
1. LOCK TABLES ๋ช…๋ น์–ด
lock tables
employee read,
department read,
client read,
assignment read,
employeeSkills read;
โ€ข /* LOCK TABLES ๋ฌธ์žฅ์˜ parameters = a list of table names and the type of
lock we would like to acquire, READ or WRITE. */
โ€ข ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” backup์„ ์œ„ํ•ด์„œ๋Š” read lock์ด๋ฉด ์ถฉ๋ถ„. ์ฆ‰, other threads
(connections) can continue to read from the tables but will be unable to
write to them while performing a backup.
โ€ข Backup์ด ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๋ฏ€๋กœ Locking์€ ์ค‘์š”.
2. FLUSH TABLES ๋ช…๋ น์–ด:
โ€ข flush tables;
โ€ข ์ „์ฒด DB ๋ฐฑ์—… ์‹œ์—๋Š” ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ํ•œ๋ฒˆ์— ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅ.
flush tables with read lock;
3. (์ค‘์š”) leave your session (where you locked and flushed the tables)
open. This makes sure that the locks are maintained. When you close
that session, the tables will be unlocked.
4. File copy ํ›„ table์„ unlockํ•  ๊ฒƒ.
158
โ€ข unlock tables;
โ€ข /* mysqlhotcopy script์™€ ๋งˆ์ฐฌ๊ฐ€์ง€, and you can restore in the same way. */
โ€ข BACKUP TABLE and RESTORE TABLE
โ€“ MyISAM table type์—๋งŒ ์ ์šฉ๊ฐ€๋Šฅ. ์˜ˆ:
โ€ข backup table t1 to 'path/to/backup';
โ€“ Windows์—์„œ๋Š” ๋“œ๋ผ์ด๋ธŒ ์ง€์ •ํ•  ๊ฒƒ.์˜ˆ:
โ€ข backup table t1 to 'c:/path/to/backup';
โ€ข /* The table will be read locked before it is backed up. */
โ€“ ์—ฌ๋Ÿฌ table์€ comma๋กœ ์—ฐ๊ฒฐ ๏ƒ  ๊ฐ table์€ ์ฐจ๋ก€๋กœ locked & backed up.
โ€ข consistent set of table์ด ํ•„์š”ํ•˜๋ฉด LOCK TABLES ๋ฌธ์žฅ์„ ๋จผ์ € ์ˆ˜ํ–‰.
โ€“ To restore from the backup,
โ€ข restore table t1 from 'c:/tmp';
โ€ข /* ๋งŒ์•ฝ ๊ฐ™์€ ์ด๋ฆ„์˜ table์ด ์žˆ๋Š” ๊ฒฝ์šฐ DROP TABLE ๋จผ์ € ์ˆ˜ํ–‰ ํ›„ RESTORE. */
โ€ข Restoring from the Binary Log
โ€“ ๋Œ€๋ถ€๋ถ„; backup์œผ๋กœ๋ถ€ํ„ฐ restoreํ–ˆ์„ ๋•Œ๋Š” ์ฒ˜์Œ backupํ•œ ์ด๋ž˜๋กœ ๋ฐœ์ƒํ•œ
insert/update๋ฅผ ๋ฐ˜์˜ํ•˜๋Š” ์ž‘์—…์ด ํ•„์š”.
โ€“ ์ด๋“ค ๋ณ€๊ฒฝ์‚ฌํ•ญ์€ binary log or update log์— ์ €์žฅ๋˜์–ด ์žˆ๋‹ค.
โ€ข mysqlbinlog logfile > updates.sql
โ€“ (์ฃผ์˜) ์ž‘์—… ๋‚ด์—ญ์„ ๋ฏธ๋ฆฌ ์ ๊ฒ€! ์˜ˆ:
โ€ข update user set password='password';
โ€ข ์ฆ‰, ์ด๋Ÿฐ ์ž‘์—…์ด ์žฌ ์‹คํ–‰๋˜์ง€ ์•Š๋„๋ก ์ฃผ์˜.
159
Testing Your Backup
โ€“ โ€ฆ
โ€“ Testํ•  ๊ฒƒ
โ€“ ํŠนํžˆ install ๋ฐ recovery์—์„œ binary log๊ฐ€ ์ค‘์š”.
โ€ข It is not enabled by default, but it is needed to bring a
restored database back up to date.
160
Checking and Repairing Tables
โ€ข Checking tables for corruption is part of routine job
โ€ข MySQL์—์„œ table checkํ•˜๋Š” 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•:
โ€“ CHECK TABLE
โ€“ myisamchk (or isamchk)
โ€“ Mysqlcheck
โ€ข ๋ฌธ์ œ table์˜ repair;
โ€“ REPAIR TABLE or
โ€“ again myisamchk (or isamchk) or mysqlcheck.
โ€ข ์–ด๋–ค option์„ ์‚ฌ์šฉํ• ์ง€๋ฅผ ์ •ํ•˜๋Š”๋ฐ ๊ณ ๋ คํ•ด์•ผ ํ•  ์‚ฌํ•ญ:
CHECK /REPAIR ๋ช…๋ น์–ด๋Š” MySQL๋‚ด์—์„œ, ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋“ค์€ ๋ช…๋ น์–ด ์ค„์—์„œ ์ˆ˜ํ–‰.
CHECK /REPAIR ๋ช…๋ น์–ด๋Š” MyISAM๊ณผ InnoDB table ๋ชจ๋‘์— ์ ์šฉ
isamchk script๋Š” ISAM์—, myisamchk์™€ mysqlcheck๋Š” MyISAM์— ์ ์šฉ.
myisamchk /isamchk ์ด์šฉ ์‹œ๋Š” table์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์ง€ ์•Š์•„์•ผ ํ•˜๋ฏ€๋กœ
locking ๋“ฑ์˜ ์กฐ์น˜. ๏ƒŸ๏ƒ  ์ž์นซ data corruption.
โ€“ CHECK, REPAIR, and mysqlcheck are all safe to use when the server
is up and tables are in use.
โ€“ (๊ณ„์†)
โ€“
โ€“
โ€“
โ€“
161
โ€ข Checking and Repairing Tables with CHECK and REPAIR
โ€“ ์˜ˆ:
check table department; /* MyISAM and InnoDB tables ๋ชจ๋‘ ๊ฐ€๋Šฅ. */ ๏ƒจ
+-----------------------------+---------+-------------+-------------+
| Table
| Op
| Msg_type | Msg_text |
+-----------------------------+---------+-------------+-------------+
| employee.department
| check | status
| OK
|
+-----------------------------+---------+-------------+-------------+
1 row in set (0.00 sec)
โ€“ ๋˜๋Š” โ€œTable is already up to dateโ€, ์ฆ‰, everythingโ€™s fine.
โ€“ ๋‹ค๋ฅธ message =๋ฌธ์ œ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด๋ฏ€๋กœ ๏ƒ  REPAIR TABLE :
repair table t1;
โ€“ Repair๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ๋˜๋ฉด (or ์• ๋‹น์ดˆ repair๊ฐ€ ๋ถˆํ•„์š”ํ–ˆ์œผ๋ฉด) ๏ƒจ
+---------+--------+--------------+-------------+
| Table | Op
| Msg_type | Msg_text |
+---------+--------+--------------+-------------+
| test.t1 | repair | status
| OK
|
+---------+---------+--------------+-------------+
1 row in set (0.03 sec)
โ€“ If you get any message other than OK, the REPAIR hasn't worked
and you will need to resort to the more powerful myisamchk.
162
โ€ข Checking and Repairing Tables with myisamchk
โ€“ (์ฃผ์˜) myisamchk ์‚ฌ์šฉ ์‹œ stop the server!
โ€“ ์šฉ๋ก€:
myisamchk table /* at the command prompt. */
โ€ข /* The table should be the path to a .MYI file that represents a MyISAM
table. This will report virtually all errors. If it doesn't seem to be finding
your problem, you can try running it with the -m switch. The default
behavior looks for corruption in the indexes; with this switch, the rows
are scanned as well. */
โ€“ myisamchk์„ ์ด์šฉํ•œ repair
โ€ข -q -r options for quick recovery, as shown here:
myisamchk -q -r table
โ€ข /* ์•ˆ๋˜๋ฉด back up the data file and try a full recovery: */
myisamchk -r table
โ€ข /* ์•ˆ๋˜๋ฉด try --safe-recover option ; -r ๋กœ ์ฒ˜๋ฆฌ ์•ˆ๋œ error๋ฅผ fix: */
myisamchk --safe-recover table
โ€ข /* myisamchk ์„ parameter์—†์ด ์ž…๋ ฅํ•˜๋ฉด ๋งŽ์€ option์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. */
163
โ€ข Checking and Repairing Tables with mysqlcheck
โ€“ mysqlcheck program ; checks MyISAM and InnoDB tables and
repairs MyISAM tables safely while the server is up and running.
โ€ข mysqlcheck -u username -p employee
โ€“ ์•„๋ฌด ๋ฌธ์ œ ์—†์„ ๋•Œ์—๋Š” ๏ƒจ
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
employee.assignment
employee.client
employee.department
employee.employee
employee.employeeSkills
OK
OK
OK
OK
OK
โ€“ --databases switch ; specifies a list of databases to check
โ€“ --all-databases option ; checks all the databases on the server.
โ€“ -r option ; repairs any corrupted MyISAM tables that it encounters.
164
15. Securing Your MySQL
Installation
165
How the Privilege System Works in Practice
โ€ข two stages to the privilege system.
โ€“ 1 ๋‹จ๊ณ„
โ€ข ์‚ฌ์šฉ์ž๊ฐ€ ์„œ๋ฒ„์— ์—ฐ๊ฒฐํ•ด๋„ ๋˜๋Š”์ง€ ํ™•์ธ โ€“์ž…๋ ฅ๋œ username/ password๊ณผ host
๋ฅผ ๋น„๊ต -- user table ์ด์šฉ. ์ฆ‰, matching row๊ฐ€ ์žˆ์–ด์•ผ ๋จ
โ€ข user table์ด host column์—์„œ wildcard๋ฅผ ์ง€์›ํ•˜๋ฏ€๋กœ user/hostname
combination์ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ row์— match๋  ์ˆ˜ ์žˆ๋‹ค. MySQL determines which
row is relevant by matching the most specific hostname first.
โ€“ ์˜ˆ: if there are rows in the table for test from host localhost and user test
from host % (meaning any host), then the localhost row will be selected.
Note that these two rows can have different passwords. ๏ƒ  confusion.
โ€“ 2 ๋‹จ๊ณ„
โ€ข ํŠน์ • query or command ์ˆ˜ํ–‰ ์‹œ grant table๋กœ ํ™•์ธ ํ›„ ์ˆ˜ํ–‰.
โ€“ ์ˆ˜ํ–‰ํ•˜๋ ค๋Š” query๊ฐ€ global privilege๋ฅผ ํ•„์š”๋กœ ํ•˜๋Š” ๊ฒฝ์šฐโ€”์˜ˆ: LOAD DATA INFILE
or trying to use SHOW PROCESSLISTโ€”user table์„ check.
โ€“ For database-specific queries, the user table will be checked first.
โ€“ If the user has the privilege on all databases, this will be sufficient.
โ€“ If not, then the db and host tables are checked.
โ€“ If (์—ฌ๊ธฐ์„œ๋„ ํ™•์ธ ์•ˆ๋˜๋ฉด) then ๋งˆ์ง€๋ง‰์œผ๋กœ table- or column-level privileges ํ™•์ธ.
166
Securing Accounts
โ€ข Setting the Password for the Root Account
โ€“ MySQL์„œ๋ฒ„ ์„ค์น˜ ์‹œ ๋ฐ˜๋“œ์‹œ ์ฆ‰๊ฐ root password๋ฅผ ๋จผ์ € ์„ค์ •ํ•  ๊ฒƒ. (default์„ค์ • x)
โ€ข Deleting Anonymous Accounts
โ€“ MySQL์„ Windows์— ์„ค์น˜ํ•  ๋•Œ, ์ž๋™์ ์œผ๋กœ ํŠน์ • account๋ฅผ ์ƒ์„ฑ
โ€“ Linux์˜ ๊ฒฝ์šฐ์—๋Š” mysql_install_db script์ˆ˜ํ–‰ ์‹œ ๋ฐœ์ƒ.
โ€“ Two of these accounts are anonymous; (No passwords set by default)
โ€ข host value of localhost and
โ€ข % (any other host, so effectively any remote connection).
โ€“ Delete these accounts!!
delete from user where User=โ€˜ โ€˜;
delete from db where User=โ€˜ โ€˜;
โ€ข /* follow this with FLUSH PRIVILEGES to flush the grant tables. */
โ€“ (๋‹ค๋ฅธ ์ด์œ ) ์ด๋“ค account๊ฐ€ ํ˜ผ๋ž€์•ผ๊ธฐ when regular users try to log in.
โ€ข ์˜ˆ์ปจ๋Œ€ laura ๋ผ๋Š” username at any host (%)๋ฅผ ์ƒ์„ฑ ๏ƒ 
โ€ข laura tries to connect from localhost ๏ƒ  MySQL server looks for matching entries in
the user table. It has laura@% and (anonymous)@localhost.
โ€ข ์ด๋•Œ MySQL์€ the most specific hostname์„ ์šฐ์„ ์ ์œผ๋กœ match์‹œํ‚ค๋ฏ€๋กœ matching
row๋Š” (anonymous)@localhost๊ฐ€ ๋œ๋‹ค. Note that although laura has supplied a
username, this doesn't matter! The anonymous accounts don't require a username.
This anonymous account is likely to have a different password from laura's account
(by default, the password is blank, meaning the user should not supply one). ์ฆ‰,
when laura tries to log in with her username and password from localhost, she will
get an Access Denied error for no obvious reason.
167
โ€ข Dangerous Privileges
โ€“ MySQL has a very fine-grained privilege system์„ ๊ฐ€์ง„๋‹ค. (Ch 11) ๋”ฐ
๋ผ์„œ privilege grant์‹œ ์ฃผ์˜. ํŠนํžˆ FILE, PROCESS, and WITH GRANT
OPTION์„ ์กฐ์‹ฌํ•  ๊ฒƒ!
โ€“ FILE privilege ; allows users to LOAD DATA INFILE. This can be
manipulated to load in files from the server (such as the password
file /etc/passwd) or even database data files, effectively
circumventing the privilege system.
โ€“ PROCESS privilege ; allows users to SHOW PROCESSLIST. (์ด๋•Œ ์ˆ˜
ํ–‰ ์ค‘์ธ query ๋“ฑ ์‚ฌ์šฉ์ž ๊ด€๋ จ ์ •๋ณด๊ฐ€ ์œ ์ถœ๋  ๊ฐ€๋Šฅ์„ฑ)
โ€“ WITH GRANT OPTION privilege ; allows a user to share his
privileges with others. ๋”ฐ๋ผ์„œ ์œ„ํ—˜์„ฑ์„ ๋ช…ํ™•ํžˆ ์ธ์‹ํ•œ ์ƒํƒœ์—์„œ๋งŒ ์‚ฌ์šฉ.
โ€ข Passwords and Encryption
โ€“ MySQL user passwords are encrypted. Before version 4.1, you
could use the encrypted password as stored to log in. This has now
been fixed.
โ€“ (non-MySQL) username ๋ฐ password ์ €์žฅํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ ๊ฐœ๋ฐœ ์‹œ
PASSWORD() ํ•จ์ˆ˜๋ณด๋‹ค๋Š” MD5() or ENCRYPT()๋ฅผ ์ด์šฉํ•  ๊ฒƒ.See Ch 8.
168
Securing Your Installation Files
โ€“ ์•ž์„œ์˜ ํ•ญ๋ชฉ ์ด์™ธ์—๋„ MySQL binaries, scripts, and data files์— ๋Œ€ํ•œ
access๋ฅผ ํ†ต์ œํ•  ๊ฒƒ!
โ€ข Don't Run mysqld as Root
โ€“ โ€ฆ
โ€“ (Web server ์—์„œ์ฒ˜๋Ÿผ) ๋ณ„๋„ ๊ณ„์ •์„ ์ƒ์„ฑ
โ€ข Access and Privileges Under Your Operating System
โ€“ ๋ฌด์—‡๋ณด๋‹ค control file access in your operating system !!
โ€ข MySQL binaries, scripts, ํŠนํžˆ data directory์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž access๋ฅผ ํ†ต์ œ!
โ€ข ํ”ํ•œ ์˜ค๋ฅ˜ = ์„œ๋ฒ„๊ฐ€ ์žˆ๋Š” ์‹œ์Šคํ…œ์— ๊ณ„์ •์„ ๊ฐ€์ง„ ์ž๊ฐ€ ์ž์นซ ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ† ๋ฆฌ์—
๋“ค์–ด์™€์„œ ๋‹ค๋ฅธ MySQL ์„œ๋ฒ„๋กœ ๋ฐ์ดํ„ฐ ๋ณต์ œํ•˜๋Š” ๋ฌธ์ œ.
โ€“ (following safeguards)
โ€ข Only appropriate users can run mysqld.
โ€ข ์ ์ ˆํ•œ ์‚ฌ์šฉ์ž๋งŒ์ด
โ€“ MySQL์— ์—ฐ๊ด€๋œ program๊ณผ script์— accessํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•  ๊ฒƒ. (์˜ˆ:
mysqladmin, mysqldump, mysqlhotcopy. โ€“ program ๋ณ„๋กœ ๊ฒ€์‚ฌํ•  ๊ฒƒ).
โ€“ MySQL data directory์— accessํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•  ๊ฒƒ. If the server is running as
user mysql, this user will need access to the directory. Any other users are
optional and are therefore generally best denied.
169
Filtering User Data
โ€ข Before passing on any user-entered
data to MySQL, you should do some
application-level error checking.
โ€“ ์˜ˆ: user name์—์„œ์˜ โ€˜ (apostrophe)
170
Other Tips
โ€ข Using SSL Connections
โ€“ โ€ฆ
โ€“ OpenSSL library (available from www.openssl.org)๋ฅผ ์„ค์น˜ํ•˜๊ณ  start
the server with the --with-vio and --with-ssl options, and do some
setup at the command line. (MySQL manual ์ฐธ์กฐ)
โ€“ ์„ค์น˜ ํ›„ restrict GRANT statements by requiring users to connect
using SSL or to have an appropriate certificate. ์˜ˆ:
โ€ข grant all on employee.*to testuser identified by 'password'require ssl;
โ€ข /* This creates (or modifies) an account for testuser, giving the user the
password password. This user will be able to connect only via SSL. You can
demand that all your users connect this way or perhaps all users logging in
from anywhere other than localhost. */
โ€ข Securing Your Installation Physically
โ€“ โ€ฆ ์ค‘์š” โ€ฆ
171
16. Replicating Your Database
172
Replication Principles
โ€ข
๋‹ค์–‘ํ•œ Replication ํ˜•ํƒœ ์ค‘ MySQL์€ directional master-slave relationship.
โ€“ Master controls what data is stored, while the slaves try to mirror that content.
โ€“ Master์˜ binary log stores details of every query executed on the server since
logging was enabled. Slaves are sent queries from the master's binary log to
apply to their own stored data.
โ€“ ์ผ๋ฐ˜์ ์œผ๋กœ write operation์€ ์ง์ ‘ master์— ์ˆ˜ํ–‰ํ•˜๊ณ  read operation์€ ๋ชจ๋“  slave ๋˜
๋Š” master-slave๊ฐ„์— ๊ณต์œ . ๏ƒŸ ํ†ต์ƒ application logic.
โ€“ (์œ ์˜) ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ง„ ๊ธฐ์กด database์— replication ์ถ”๊ฐ€ ์‹œ ๏ƒ  the binary log may be
incomplete. Binary logging๋Š” ์ž๋™ (by default) ๊ตฌ๋™๋˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ฏ€๋กœ ์ •์ƒ์  ๋ณต์ œ๋ฅผ
์œ„ํ•ด์„œ๋Š” binary log ์‹œ์ž‘ํ•  ์‹œ์ ์— ๋ชจ๋“  slave๊ฐ€ master์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค. ๏ƒ 
โ€“ A thread on the slave connects to a thread on the master and requests new
events. These are stored in a relay log on the slave. A separate thread on the
slave reads events from the local relay log and executes the queries on the local
mirror of the data.
โ€“ Master์™€ slave๊ฐ€ ์„œ๋กœ ๋‹ค๋ฅธ ์‹œ์ ์— ์‹œ์ž‘๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ (์˜ˆ: query๋„์ค‘ ์‹œ์Šคํ…œ ์ถ”๊ฐ€ ๋˜๋Š”
๋„คํŠธ์›Œํฌ fail ๋˜๋Š” bottleneck๋ฐœ์ƒ), slaves need to be able to keep track of where
they are in the log of updates to be performed. It is important that atomic
transactions are honored and updates are performed in order.
โ€“ ๋Œ€๋ถ€๋ถ„ consistent state๋กœ ๋ณต์ œ๋˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ช‡ ๋ถ„ (์ดˆ)์˜ ์‹œ๊ฐ„์ฐจ์ด๋Š” ํฌ๊ฒŒ ์ค‘์š”์น˜ ์•Š๋‹ค.
โ€“ (๋‚ด๋ถ€์ž‘์šฉ) Updates are asynchronous and do not happen in real time. Queries sent
to different servers can give different results for some time after an update is
made. This can be seen as a negative, but the positive side is that if you have a
slave running on a portable device or an unreliable network, it will happily operate
for long periods between updating data from the master.
โ€ข
A Note on Versions
โ€“ MySQL (3.23.15)๋ถ€ํ„ฐ ์ ์šฉ. ๊ฐ€๊ธ‰์  ์ตœ์‹  version์œผ๋กœโ€ฆ Older version์ด ๋ถˆ๊ฐ€ํ”ผํ•˜๋ฉด
173
โ€ข www.mysql.com/doc/en/Replication_Implementation.html
Setting Up and Configuring for Replication
โ€ข (์ผ๋ฐ˜๋ก )
โ€“ Internet์‚ฌ์šฉ ์‹œ ๋ณด์•ˆ ๋ฌธ์ œ
โ€“ 3306 default port๊ฐ€ firewall์„ ํ†ต๊ณผํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธ.
โ€ข Create a Replication User
โ€“ Master์—์„œ์˜ replication์„ ์œ„ํ•œ ๊ณ„์ • ๏‚น root
โ€“ If you are going to populate your slaves initially by using LOAD
TABLE FROM MASTER or LOAD DATA FROM MASTER, your
replication user needs a special set of permissions.
โ€“ ์˜ˆ: ์—ฐ๊ฒฐ์„ค์ •์„ ์œ„ํ•ด์„œ๋Š” ํ•„์š” permission์„ ๊ฐ€์ง„ ์‚ฌ์šฉ์ž ๊ณ„์ •์„ ์ƒ์„ฑ
grant replication slave, reload, super, select
on logs.*
to replication@" %" identified by 'password';
โ€ข (Note: ์—ฌ๊ธฐ์„œ๋Š” logs database ์ด์šฉํ•˜๋ฏ€๋กœ ์ด๋ฅผ ๋ณ€๊ฒฝ์‹œ์ผœ ์ค„ ๊ฒƒ.)
โ€“ ์ผ๋‹จ initial copy from master to slave๊ฐ€ ์™„์ „ํžˆ ์ˆ˜ํ–‰๋˜๋ฉด replication
์‚ฌ์šฉ์ž๋Š” ๊ทธ๋ฆฌ ๋งŽ์€ permission์„ ํ•„์š”๋กœ ํ•˜์ง€ ์•Š๋Š”๋‹ค. If you are
populating your slaves from a backup or reducing the user's
permissions after the initial copying is complete, the user needs
only the replication permission, so the following query will create
a user named replication that can connect from any of the slave
servers (and any other machines):
โ€ข grant replication slave on logs.* to replication@"%"
'password';
identified by
174
โ€ข Check Master Configuration
โ€“ Master server์—์„œ๋Š” binary logging์ด enabled ๋˜์–ด์•ผ ํ•œ๋‹ค. โ€ฆ
โ€“ ํ™•์ธ:
โ€ข show variables; /* ๏ƒ  complete list */
โ€ข show variables like "log_bin" ; /*, but for concise output */
โ€“ If binary logging is off, add log-bin to options file as in Listing 1.1.
โ€ข
โ€ข
โ€ข
โ€ข
Options file์˜ ์ด๋ฆ„= my.ini or my.cnf (์šด์˜์ฒด์ œ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง)
Edit your my.ini/my.cnf file to give your master server a unique id. ์˜ˆ:
[mysqld] log-binserver-id=1
์—ฌ๊ธฐ์„œ server-id๋Š” MySQL ์„œ๋ฒ„๋งˆ๋‹ค ํ• ๋‹น๋˜๋Š” unique identifier ๋กœ์„œ ์–‘์˜ ์ •์ˆ˜
(a positive integer)์—ฌ์•ผ ํ•œ๋‹ค.
โ€“ options file ํŽธ์ง‘ ํ›„์—๋Š” ์„œ๋ฒ„๋ฅผ restartํ•ด์•ผ ํšจ๋ ฅ ๋ฐœ์ƒ.
175
โ€ข
โ€“
โ€“
Create a Master Snapshot
Replication์„ ์œ„ํ•ด์„œ ๋‹ค์Œ์˜ 3๊ฐ€์ง€๊ฐ€ ํ•„์š”
1.
2.
3.
A complete, consistent snapshot of the current database
Master ์„œ๋ฒ„์˜ binary log file ์ด๋ฆ„
The offset into the binary log where the server is currently
์ด๋“ค์€ ๋‹ค์Œ ์š”์ธ์— ์˜ํ•ด ์˜ํ–ฅ (i) MyISAM or InnoDB tables (ii) ํŠน์ • ๊ธฐ
๊ฐ„ ๋‚ด์— ์„œ๋ฒ„ ์ •์ง€๋ฅผ ์–ผ๋งˆ๋‚˜ ํ—ˆ์šฉํ•  ๊ฒƒ์ธ๊ฐ€์˜ ๋ฌธ์ œ.
โ€ข
โ€ข
MyISAM table; you can grab a snapshot after you start each slave. ; ๋น„
ํšจ์œจ์ , ํŠนํžˆ if you have a large amount of data and many slaves. For
each slave, the LOAD DATA FROM MASTER query will obtain a lock on
the master's data and hold it until a complete copy has been transmitted.
You can lock the databases for a much shorter time by making the
snapshot manually via the file system. This will also allow you to use
one snapshot to start as many slaves as required, reducing time when
the server is locked.
InnoDB table; LOAD DATA FROM MASTER query option์ด ์—†๋‹ค.
โ€“
โ€“
โ€“
You can make a file-system snapshot or buy the hot backup tool.
์ด ๊ฒฝ์šฐ ์šฐ์„  ๋‹ค์Œ ๋ช…๋ น์„ ํ†ตํ•ด ๋ณด๊ด€๋œ ๋ฐ์ดํ„ฐ๊ฐ€ consistent & up-to-date ํ•œ์ง€ ํ™•์ธ.
get the current binary log file and offset
flush tables with read lock; /* This will also lock the table. */
show master status;
+-------------------------+------------+------------------+------------------------+
| File
| Position
| Binlog_do_db | Binlog_ignore_db
|
+-------------------------+------------+-------------------+------------------------+
| server-bin.000007
|
211
|
|
|
+-------------------------+-------------+------------------+------------------------+
โ€“
์ฒซ์งธ (binary log ํŒŒ์ผ์ด๋ฆ„) ๋ฐ ๋‘˜์งธ column (offset into the binary log)๋‚ด์šฉ์„
176 ๊ธฐ๋ก.
์ด๋“ค ๋‚ด์šฉ์ด empty์ด๋ฉด ํŒŒ์ผ์ด๋ฆ„์œผ๋กœ๋Š” empty string ๊ทธ๋ฆฌ๊ณ  offset์œผ๋กœ๋Š” 4๋ฅผ ์ด์šฉ.
โ€“ MyISAM table์˜ snapshot์„ ๋งŒ๋“ค๋ ค๋ฉด ๋‹จ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ด€ํ•œ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ
archiving program์„ ์ด์šฉํ•˜์—ฌ ๋ณต์‚ฌํ•˜๋ฉด ๋œ๋‹ค.
โ€ข Unix์—์„œ๋Š”:
tar -cvf /tmp/snapshot.tar /path/mysql/data/logs
โ€ข Windows์—์„œ๋Š”:WinZip or ๊ธฐํƒ€ archiving tool์„ ํ†ตํ•ด grab a copy of the
directory C:\mysql\data\logs.
โ€“ copy๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ re-enable write access to the database by typing:
unlock tables;
โ€“ ์ด์ƒ์˜ ๋…ผ์˜๋Š” InnoDB table์— ๋Œ€ํ•œ ๊ฒƒ.
โ€ข If you have purchased the (commercial) InnoDB hot backup tool, it is perfect
for this task. (www.innodb.com/hotbackup.html)
โ€ข Without this tool, the safest approach is to flush and lock the database with
the following queries. Use
โ€ข flush tables with read lock;
โ€ข /* ๊ทธ๋Ÿฐ ํ›„display and record the binary log file and offset (as for MyISAM): */
show master status;
โ€“ Without unlocking the database, shut it down and make a copy of the
directory that relates to that database inside your MySQL data directory.
For InnoDB tables, you will also need to copy across the data files and
logs. After snapshot is complete, you can restart and unlock database.
177
โ€ข Configure Slaves
โ€“ ๊ฐ slave๋Š” ๊ณ ์œ ํ•œ server id๋ฅผ ํ•„์š”๋กœ ํ•˜๋ฏ€๋กœ optionsํŒŒ์ผ (my.cnf/my.ini)์— ๋‹ค
์Œ ๋‚ด์šฉ์„ ์‚ฝ์ž….
โ€ข server-id=2
โ€“ The id = positive integer (๋‹จ, ์„œ๋กœ ๋‹ค๋ฅธ ์ˆซ์ž์ด๊ธฐ๋งŒ ํ•˜๋ฉด ์–ด๋–ค ๊ฐ’๋„ ์ƒ๊ด€์—†์Œ)
If you are going to have more than a handful of servers running, an
escalating sequence is probably your best hope of keeping them unique.
โ€“ If you are working from a file-system snapshot, you need to copy the
files into the appropriate places on the slave server.
โ€“ If you are working with more than one operating system, remember to
consider filename capitalization.
โ€“ Editing your options file or copying across InnoDB files will require you to
restart your slave server.
178
โ€ข Start Slaves
change master to master_host='server',
master_user='replication',
master_password='password',
master_log_file='server-bin.000007',
master_log_pos=211;start slave;
โ€ข /* ์ด ์˜ˆ์—์„œ server = hostname of the master server.
replication = replication์„ ์œ„ํ•ด ์ƒ์„ฑํ•œ ์‚ฌ์šฉ์ž์˜ username
password = ๊ทธ ์‚ฌ์šฉ์ž์˜ ์•”ํ˜ธ.
๊ทธ ์™ธ์— binary log file name ๋ฐ offset
โ€ข START SLAVE query ; launches the slave's replication threads, causing
it to try to connect to the master and collect updates. */
โ€“ If you have copied a snapshot via the file system, you should be
able to run some matching queries against the master and slave
to check that the replication is working correctly. Make a small
update to the master and check that it is mirrored on the slave.
โ€“ If the tables you are replicating are relatively small MyISAM tables,
you can create and populate them via a query like
load table logs.logJan2003 from master; /* copy a single table or */
load data from master; /* to copy all tables onto this slave. */
โ€“ replication ๋™์ž‘ ํ›„์—๋Š” query๋ฅผ manually ์ž…๋ ฅํ•ด์„œ configure
replicationํ•˜๋Š” ๊ฒƒ์€ practicalํ•˜์ง€ ์•Š๋‹ค. (, even if only occasionally.)
๊ฐ™์€ ์ •๋ณด๊ฐ€ The options file์—์„œ๋Š” slightly different syntax! ์˜ˆ:
[mysqld]
server-id = 2
master-host = server
master-user = replication
master-password = password
replicate-do-db = logs `
179
Advanced Topologies
โ€ข ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์‚ฌ์šฉ์ฒ˜; load balancing (์ฃผ๋กœ ๋งŽ์€ read์™€ ์ƒ๋Œ€์ ์œผ
๋กœ ์ ์€ writes). ๋Œ€๋ถ€๋ถ„ single master + a small number of
slaves
โ€ข Slave ์ˆ˜๊ฐ€ ๋งŽ๊ฑฐ๋‚˜ ์ง€์—ญ์ ์œผ๋กœ spread๋˜๋ฉด cascade.
โ€“ Figure 16.1. Replication with Cascading Masters
โ€ข ์ˆœํ™˜ ๊ด€๊ณ„(circular relationship) ์‹œ ๋ณต์žกํ•ด ์งˆ ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ: ์‹œ์Šคํ…œ 2
๋Œ€๊ฐ€ ์„œ๋กœ master-slave/slave-master๋กœ ์—ฎ์ธ ๊ฒฝ์šฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์ฃผ์˜.
โ€“ Because changes are applied asynchronously, you can end up
with conflicting auto increment fields, clashing unique ids, and
inconsistent data. In some applications, this arrangement may
work well. For instance, a data logging application with few
relationships between tables that requires high throughput and
availability may be willing to sacrifice consistency.
180
Replication Future
โ€ข standard distribution ์— ํฌํ•จ๋˜์–ด ์žˆ๊ณ  ์ƒ๋‹นํžˆ ์•ˆ์ •๋˜์—ˆ์œผ๋‚˜ ์ผ๋ถ€ ๋ฏธ์ง„ํ•œ ์ :
โ€“ the process for setting up a new slave with a snapshot is not very userfriendly.
โ€“ The treatment of MyISAM tables and InnoDB tables is not consistent.
โ€“ Options for setting up SSL connections between slaves and masters.
โ€“ MyISAM์—๋„ InnoDB์—์„œ์™€ ๊ฐ™์€ hot backup tool์ด ์žˆ์„ ๊ฒƒ.
โ€ข ํ–ฅํ›„ ๊ณ„ํš:
โ€“ multimasteringโ€”ํ•˜๋‚˜์˜ slave๊ฐ€ ์—ฌ๋Ÿฌ master๋ฅผ mirrorํ•˜๋ฉด์„œ๋„ resolve conflict.
โ€“ built-in failover and load-balancing features.
โ€ข ํ˜„์žฌ๋Š” application์—์„œ ํ•ด๊ฒฐํ•˜๋˜๊ฐ€ ๋˜๋Š” 3rd-party clustering tool ํ•„์š”. (EAC)
โ€ข Some replication-related settings in the options file that are currently
unimplemented.
โ€“ Currently, if you want to make secure connections, you need to use another
product, such as Stunnel.
181
17. MySQL ์„œ๋ฒ„ Configuration์˜
์ตœ์ ํ™”
โ€ข Do it empirically.
โ€“ ํ•˜๋‚˜์”ฉ ๋ฐ”๊ฟ” ๊ฐ€๋ฉด์„œ ์ด์ „๊ณผ ๋น„๊ต
โ€“ Benchmark ์‹œ์—๋Š” log a period worth of queries (an hour, a
day, or some average period) and then replay those
queries with the new server configuration.
182
Compiling and Linking for Speed
โ€ข ์ง์ ‘ ์ปดํŒŒ์ผ ๏ƒ  ์„ฑ๋Šฅ ํ–ฅ์ƒ: extra 10% to 30%
โ€“ If you have a Pentium-based machine and run Linux,
you will be able to get a significant performance
increase by compiling MySQL with the pgcc compiler,
which optimizes for Pentium only.
โ€“ With AMD chips compiled with plain gcc.
โ€ข ํ•„์š”ํ•œ character set(s)๋งŒ ์ ์šฉํ•˜๊ณ  Compile
183
Tuning Server Parameters
โ€“ ํ˜„์žฌ์˜ ์„ค์ •์ƒํƒœ ํŒŒ์•…: show variables;
โ€“ See the effects of your server configuration:
show status;
โ€“ ํ˜„์žฌ ์„œ๋ฒ„์˜ ์ง„ํ–‰ ์ƒํ™ฉ์„ Monitor: Jeremy Zawodny's mytop Perl script.
http://jeremy.zawodny.com/mysql/mytop
โ€ข = Unix top command์™€ ์œ ์‚ฌ
โ€ข shows what processes are active, the process state, the time spent, etc.+ drill
into a MySQL process and see the actual query being executed.
โ€ข Server parameters in my.cnf options files
โ€“ MySQLโ€™s sample my.cnf files in the support-files directory.
โ€ข 4 suggested my.cnf files in this directory: my-huge.cnf, my-large.cnf, mymedium.cnf, and my-small.cnf.
โ€ข (์ดํ•˜ ๋‹ค์Œ ํŽ˜์ด์ง€์— โ€ฆ)
โ€ข 2๊ฐœ์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ parameters: key buffer์™€ table cache
โ€ข (์ด์™ธ์—๋„) ๋‹ค์–‘ํ•œ chunks of memory allocated on a per-thread basis
โ€“ read buffer size, controlled by the read_buffer_size parameter,
โ€“ The sort buffer, controlled by the sort_buffer parameter,
184
โ€ข 2๊ฐœ์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ parameters: key buffer์™€ table cache
โ€ข ์ด๋“ค์€ ์„œ๋ฒ„์—์„œ ์ˆ˜ํ–‰๋˜๋Š” ๋ชจ๋“  thread์— ๊ณต์œ ๋˜์–ด ์žˆ๋‹ค. MySQL์˜ ๋ฉ”๋ชจ๋ฆฌ ์ด
์šฉ๊ณผ ๊ด€๋ จ๋จ. ๏ƒŸ MySQLโ€™s internal buffers ๋ฐ caches๋ฅผ ํ†ตํ•ด ๊ฐ๊ฐ์˜ task์—
์ ์ ˆํžˆ ํ• ๋‹น๋˜์—ˆ๋Š”์ง€ ํ™•์ธ.
โ€“ key buffer = MyISAM indexes๊ฐ€ ๋ณด๊ด€๋˜๋Š” ๋ฉ”๋ชจ๋ฆฌ ์žฅ์†Œ.
โ€“ Index block์ด ์ด์šฉ๋  ๋•Œ ์ด๋“ค์€ buffer๋กœ load๋จ. ๏ƒ  query ์ˆ˜ํ–‰ ์‹œ ํ•ด๋‹น index
block์ด buffer์— ์žˆ์œผ๋ฉด ๊ฑฐ๊ธฐ์„œ ์ฝ๊ณ , ์—†์œผ๋ฉด disk์—์„œ keybuffer๋กœ load์‹œํ‚จ๋‹ค
(๋”ฐ๋ผ์„œ ๋Šฆ๋‹ค). ์ผ๋ฐ˜์ ์œผ๋กœ key buffer๋Š” ํด ์ˆ˜๋ก ์ข‹๋‹ค.
โ€ข key_buffer_size์˜ ๊ฒฐ์ • ๏ƒŸ ๋ฉ”๋ชจ๋ฆฌ ํฌ๊ธฐ, ์„œ๋ฒ„๊ฐ€ dedicated MySQL server
์ธ์ง€ ์—ฌ๋ถ€, index data์˜ ํฌ๊ธฐ (์ฆ‰, how big your .MYI files are in total).
โ€“ Jeremy Zawodny๋Š” dedicated์„œ๋ฒ„ ์ด ๋ฉ”๋ชจ๋ฆฌ์˜ 20% ~ 50% ๊ถŒ์žฅ. shared
machine์˜ ๊ฒฝ์šฐ ๋” ์ ๊ฒŒ ์„ค์ •! ๋˜ํ•œ index data๊ฐ€ ์ž‘์„ ๋•Œ๋„ ์ ๊ฒŒ ์„ค์ •. If you
have only 20MB of index data, there is little point in allocating 128MB to
the key buffer.
โ€ข (์ฃผ์˜) key buffer๋Š” ๋‹จ์ง€ MyISAM tables์„ ์œ„ํ•œ ๊ฒƒ์ด๋ฏ€๋กœ ๋‹ค๋ฅธ table type
์—๋Š” ๋‹ค๋ฅธ parameter ์ ์šฉํ•  ๊ฒƒ. (์˜ˆ: InnoDB table๋งŒ ์‚ฌ์šฉ ์‹œ์—๋Š”
innodb_buffer_pool_size๋ฅผ ์กฐ์ ˆ. ๏ƒŸ InnoDB buffer pool stores both
index and table data.)
โ€“ table cache์˜ ๋ฌธ์ œ - controlled via the table_cache option.
โ€ข ๋™์‹œ์— open ๋  ์ˆ˜ ์žˆ๋Š” ํ…Œ์ด๋ธ”์˜ ์ตœ๋Œ€ ๊ฐœ์ˆ˜๋ฅผ ํ•œ์ •. (์ฆ‰, MyISAM table์˜ ๊ฒฝ
์šฐ, ๊ฐ๊ฐ์˜ ํ…Œ์ด๋ธ”๊ณผ ์ธ๋ฑ์Šค๋Š” OS์ƒ์—์„œ์˜ ๊ฐœ๋ณ„์ ์ธ ํŒŒ์ผ) Opening and
closing files is slow, so these files are left open until they are
explicitly closed, the server shuts down, or the total number of open
tables exceeds the table_cache parameter.๏ƒ  table์˜ ์ˆซ์ž๊ฐ€ ๋งŽ์„ ๋•Œ๋Š”
table_cache ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ค๋ฉด ์ข‹๋‹ค. (๋˜ํ•œ OS์— ๋”ฐ๋ผ open file์˜ ์ˆ˜ ๋˜๋Š”
single process/user ๋‹น ๊ฐ€๋Šฅํ•œ open file์˜ ์ˆ˜๊ฐ€ ํ•œ์ •๋˜๋ฏ€๋กœ table_cache
185
๊ฐ’์„ resetํ•˜๊ธฐ ์ „์— ์‚ดํŽด ๋ณผ ๊ฒƒ)
โ€ข (์ด์™ธ์—๋„) ๋‹ค์–‘ํ•œ chunks of memory allocated on a perthread basis
โ€ข The value is the same for each thread, but each thread can
have this amount of memory allocated to the specified
purpose.
โ€“ read buffer size, controlled by the read_buffer_size
parameter,
โ€ข ํ…Œ์ด๋ธ” ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด full table scan ํ•  ๋•Œ ์‚ฌ์šฉ. ๋ณด๊ด€๋˜๋Š”
table data๊ฐ€ ๋งŽ์„ ์ˆ˜๋ก disk read๋Š” ์ž‘์•„์ง„๋‹ค. ๋‹จ, ์ž์นซ ๋„ˆ๋ฌด ํฌ๋ฉด ๊ฐ
๊ฐ์˜ thread์— ๋Œ€ํ•œ read buffer๊ฐ€ ๋„ˆ๋ฌด ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์†Œ๋น„ํ•  ์ˆ˜๋„
์žˆ๋‹ค. (You may want to note that this parameter was
previously called the record buffer and was controlled by the
record_buffer parameter.)
โ€“ The sort buffer, controlled by the sort_buffer parameter,
โ€ข is used when you run queries containing ORDER BY clauses.
186
Tuning Other Factors
โ€ข tips
โ€ข MySQL recommends Solaris (ํŠนํžˆ multiprocessor์‚ฌ์šฉ ์‹œ)
โ€ข Multiple disk ์‚ฌ์šฉ ์‹œ ๊ฐ๊ฐ์˜ database์— ์ ํ•ฉํ•œ disk ์‚ฌ์šฉ.
โ€“ RAIDโ€”RAID 0 will improve reading and writing performance,
and RAID 1 or 5 will improve reading performance.
โ€ข Consider use of a journaling file system, such as Reiserfs
or XFS.
โ€ข Fast networks when using replication.
187
Chapter 18. Optimizing Your Database
โ€ข ์ผ๋ฐ˜์ ์ธ database design guidelines and normalization
+
โ€ข What's slow in MySQL databases?
โ€ข Making the right design choices
โ€ข Using indexes for optimization
โ€ข Using OPTIMIZE TABLE
188
What's Slow in MySQL Databases?
โ€ข Server optimize ํ›„ ๋‹ค์Œ ์‚ฌํ•ญ ๊ฒ€ํ† :
โ€“ Not using enough indexes.
โ€ข ๊ฐ€์žฅ ํ”ํ•œ ๋ฌธ์ œ = tables that have no indexes or that are
without indexes on columns you are searching.
โ€ข ๊ทธ๋ ‡๋‹ค๊ณ  index๊ฐ€ ๋งŽ์„ ์ˆ˜๋ก ์ข‹์€ ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค. ๏ƒ 
โ€“ Using too many indexes.
โ€ข If you are retrieving data, indexes are good.
โ€ข When you are inserting new rows, updating rows, or deleting
rows, indexes are no longer your friends. When you update
data, the indexes need updating too, increasing the amount of
overhead you have to deal with.
โ€“ Using table- and column-level privileges.
โ€ข ๋งŽ์€ resource์— table- or column-level privileges ์„ค์ •ํ•˜๋ฉด
MySQL์ด ์ด๋ฅผ query์‹œ๋งˆ๋‹ค ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.
โ€“ Making the wrong database design choices.
โ€ข โ€ฆ
189
Making the Right Design Choices
โ€ข
Use the smallest type that data will fit in.
โ€“ ์˜ˆ: storing numbers of 1 ~10: INT ๋Œ€์‹  TINYINT ์‚ฌ์šฉ.
โ€“ Row์™€ table์ด ์ž‘์„ ์ˆ˜๋ก ๊ฒ€์ƒ‰์ด ๋น ๋ฅด๋‹ค. + ๋ฐ์ดํ„ฐ๊ฐ€ ์ ์„ ์ˆ˜๋ก ๋” ๋งŽ์€ row๋ฅผ cache.
โ€ข
Use fixed-length records where possible.
โ€“ โ€ฆ
โ€“ no VARCHAR, no TEXT, and no BLOB.
โ€ข
โ€ข
If you need to store TEXT and BLOB, you might consider denormalizing
your schema to break the TEXT or BLOB fields out into a separate table.
VARCHAR๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ CHAR๋กœ ๋ณ€ํ™˜์„ ๊ฒ€ํ† .
โ€“ = a trade-off with more space on disk, against suggestion above
โ€ข
Declare as many columns NOT NULL as possible.
โ€“ If your data logically requires NULL values, then obviously you should use them.
๋‹จ, small speed and storage space price for NULL.
โ€ข
Choose the table type on a table-by-table basis.
โ€“ Non-transaction-safe tables (MyISAM) involve a lot less overhead ๏ƒ  faster than
the transaction-safe types (InnoDB and BDB).
โ€ข
โ€ข
Choose appropriate indexes.
๊ทน๋‹จ์ ์ธ ๊ฒฝ์šฐ even consider denormalization of tables to reduce the number
of joins made for common queries.
โ€“ ๋‹จ, ๊ด€๋ฆฌ๊ฐ€ ์–ด๋ ค์›Œ์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ์กฐ์‹ฌํ•ด์„œ ๊ฒฐ์ •ํ•  ์‚ฌํ•ญ.
190
Indexing for Optimization
โ€ข ๊ฐœ์š”
โ€“ check if database has any indexes. (๏ƒŸ DESCRIBE ๋ช…๋ น์–ด)
โ€ข index = a lookup table to find specific rows in a table quickly.
โ€“ Indexes in MySQL are stored as b-trees
โ€“ can be on a single column or can span multiple columns (just like keys).
An index will be used when running a query, if the search is being
performed on the following:
โ€ข A single column that has a single-column index. ์˜ˆ: if we index departments
on departmentID and perform a query like SELECT...WHERE departmentID=n.
โ€ข A set of columns that forms a multicolumn index. ์˜ˆ: if we have created an
index on the employee.assignment table on (clientID, employeeID, workdate)
and we perform a query like SELECT...WHERE clientID=x AND employeeID=y
AND workdate=z.
โ€ข A column or set of columns that forms a subset of a multicolumn index, as long
as there is a leftmost prefix of the index columns. ์˜ˆ: with the assignment
table as before, with an index on (clientID, employeeID, workdate), indexes
would be used for these types of queries:
โ€ข SELECT...WHERE clientID=x
โ€ข SELECT...WHERE clientID=x AND employeeID=y
โ€“ But, they would not be used for this type:
โ€ข SELECT...WHERE employeeID=y AND workdate=z
โ€“ (ํ•˜๋‚˜ ๋˜๋Š” ์—ฌ๋Ÿฌ column์— ๋Œ€ํ•ด) queries that does not fit the preceding
criteria๊ฐ€ ๋งŽ์€ ๊ฒฝ์šฐ, run CREATE INDEX statement to create an
191
appropriate index. Note that MySQL can use only one index per table in
a single query. It cannot combine existing indexes automatically.
ANALYZE TABLE
โ€ข use the ANALYZE TABLE statement to
review and store the key distribution in
a table.
โ€“ MySQL stores this information and uses it to
decide how to execute joins.
โ€ข analyze table tablename ;
192
Using OPTIMIZE TABLE
โ€ข = MySQL equivalent of defragmenting your hard disk.
โ€ข OPTIMIZE TABLE tablename;
โ€“ use OPTIMIZE TABLE periodically โ€ฆ
โ€“ ๏ƒ  ์Šคํ† ๋ฆฌ์ง€๋ฅผ ์ž˜ ์ •๋ˆํ•˜๊ณ , re-sort the index, and update
statistics for the table.
โ€“ MyISAM and BDB tables ์—๋งŒ ์ ์šฉ
193
19. Query ์ตœ์ ํ™”
โ€ข ๊ฐœ๋ณ„ query ๋ถ„์„์„ ํ†ตํ•ด ์„ฑ๋Šฅํ–ฅ์ƒ ๊ฐ€๋Šฅ.
โ€ข In this chapter:
โ€“
โ€“
โ€“
โ€“
โ€“
โ€“
Finding slow queries
Benchmarking your queries
Using the slow query log
Using EXPLAIN to see how queries are executed
Understanding MySQL's built-in query optimization
Optimization tips
194
Finding Slow Queries
โ€ข ์‹œ๊ฐ„์„ ๋งŽ์ด ์†Œ์š”ํ•˜๋Š” ๋ถ€๋ถ„์ด ์–ด๋Š ๊ณณ์ธ์ง€ ์ฐพ๋Š”๋‹ค.
โ€“ Observation: ํ”ํžˆ ํŠน์ • query๊ฐ€ ๋Šฆ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐœ๊ฒฌ
โ€“ Benchmarking: Test your application to see which
parts of it are slow.
โ€“ Slow query log: This log tracks slow queries, as you
might expect from its name.
โ€ข ์ผ๋‹จ ์‹œ๊ฐ„์ง€์ฒด ๋ถ€๋ถ„์„ ํ™•์ธํ•˜๋ฉด ๊ทธ ์›์ธ ๋“ฑ์„
EXPLAIN ์„ ํ†ตํ•ด ๋ถ„์„ํ•˜๊ณ  optimize the query.
โ€ข ๋ชจ๋“  query๋ฅผ speed up ํ•  ํ•„์š”๋Š” ์—†๋‹ค. ๊ฐ€์žฅ ์˜ํ–ฅ
๋„๊ฐ€ ํฐ ๋ถ€๋ถ„์— ์ฃผ๋ ฅ. ์ž˜๋ชปํ•˜๋ฉด ์ž‘์€ ์„ฑ๋Šฅ๊ฐœ์„ ์— ๋งŽ
์€ ์‹œ๊ฐ„์ด ์†Œ์š”๋˜๊ธฐ๋„ ํ•œ๋‹ค.
195
Benchmarking Your Queries
โ€ข Benchmarking = timing how long your queries take.
โ€“ by running a query many times โ€ฆ
โ€ข ๏ƒŸ A single execution of the query will be subject to load issues
โ€ข ๋˜ํ•œ 2๋ฒˆ์งธ๋กœ ์‹ค์‹œํ•˜๋ฉด query์ˆ˜ํ–‰์ด ๋นจ๋ผ์ง„๋‹ค. ๏ƒŸ the query is cached.
โ€“ ๋˜ํ•œ external scripts or programs ๋ฅผ ์ด์šฉํ•˜๊ธฐ๋„ ํ•จ.
โ€ข ์˜ˆ: download the source distribution of MySQL and look at the benchmarking
code that is included in the sql-bench directory.
โ€“ ๋˜ํ•œ built-in BENCHMARK() function ์‹ค์‹œ
โ€ข ์˜ˆ: select benchmark(1000000, 6*9); ๏ƒจ
+-----------------------------------+
| benchmark(1000000, 6*9)
|
+-----------------------------------+
|
0
|
+-----------------------------------+
1 row in set (0.25 sec)
โ€ข /* 2 parameters: the number of times to evaluate the expression (์—ฌ๊ธฐ์„œ๋Š” 1๋ฐฑ
๋งŒ) and the expression we want to evaluate (์—ฌ๊ธฐ์„œ๋Š” six times nine). */
โ€ข BENCHMARK() function ๊ฒฐ๊ณผ๊ฐ’์€ ํ•ญ์ƒ 0์ด๋ฏ€๋กœ ์˜๋ฏธ ์—†๊ณ  ๋Œ€์‹  query ์ˆ˜ํ–‰์‹œ๊ฐ„์ด ์ค‘์š”.
(์—ฌ๊ธฐ์„œ๋Š” evaluating 6x9 one million times took a quarter of a second.)
โ€“ ๋˜ํ•œ pass BENCHMARK() a query, ์˜ˆ:
select benchmark(10000000, 'select employee.name, department.name from
employee, department where
196
employee.departmentID=department.departmentID');
Using the Slow Query Log
โ€ข (๋ชฉ์ ) ์–ด๋–ค query๊ฐ€ ๋Šฆ์€์ง€ ์ถ”์ (track) (๋‹จ์œ„: ์‹œ๊ฐ„)
โ€ข (๋ฐฉ๋ฒ•) turn on slow query logging with the --log-slowqueries=filename option when starting the MySQL server or in
your configuration file.
โ€“ If you also turn on the --log-long-format option, all queries that
run without using an index are also logged. This can help you to
see where you should be targeting your optimization efforts.
โ€“ You can define what is meant by a slow query by using the
long_query_time variable. You can set this in your configuration
file or by using the SET command. This variable is in seconds.
โ€“ slow query log๋Š” text file์ด๋ฏ€๋กœ ์ง์ ‘ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. Summary๋งŒ ๋ณผ ์ˆ˜๋„
์žˆ๋‹ค. ๏ƒŸ by running the mysqldumpslow script (in the scripts
directory of your MySQL installation. ๋˜ํ•œ Perl script์ด๋ฏ€๋กœ
Windows์—์„œ๋Š” Perl ์„ค์น˜ ํ•„์š”)
โ€ข (ํ•œ๊ณ„) you cannot configure it to log slow queries that take
less than one second. The administrator might want to be
informed when queries take more than one-tenth of a second
or some other fraction. ๏ƒ  future version.
197
Using EXPLAIN to See How Queries Are Executed
โ€ข
์˜ˆ:
explain
select e.name, d.name
from employee e, department d
where e.departmentID = d.departmentID; ๏ƒจ
+----+-------------+-------+--------+---------------+--------------+-----------+-----------------------+------+--------+
| id | select_type | table | type | possible_keys| key
| key_len | ref
| rows | Extra |
+----+-------------+-------+--------+---------------+--------------+-----------+-----------------------+------+--------+
| 1 | SIMPLE
|e
| ALL
| NULL
| NULL
| NULL
| NULL
| 5 |
|
| 1 | SIMPLE
|d
| eq_ref | PRIMARY
| PRIMARY | 4
| e.departmentID | 1 |
|
+----+-------------+-------+--------+----------------+-------------+------------+----------------------+------+--------+
2
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
โ€ข
rows in set (0.00 sec)
/* table๋‹น ํ•˜๋‚˜์˜ row. Row์˜ ์ˆœ์„œ = table์ด join๋œ ์ˆœ์„œ.
id = a sequence number. (์˜ˆ์ปจ๋Œ€ subquery์‚ฌ ์šฉ์‹œ, each SELECT is numbered.)
select_type =(๋Œ€๋ถ€๋ถ„์€ SIMPLE (a plain vanilla SELECT). subqueries ์‚ฌ์šฉ ์‹œ์—๋Š”, the outer query
๊ฐ€ PRIMARY, inner queries๊ฐ€ SUBSELECT or DEPENDENT SUBSELECT)
table This is the table this row is about.
type ; tells you how the table is being joined to the other tables in the query.
possible_keys ; ์–ด๋–ค index๊ฐ€ ์ด์šฉ๋  ์ˆ˜ ์žˆ์—ˆ๋Š”์ง€ ํ‘œ์‹œ (relevant indexes ๊ฐ€ ์—†์œผ๋ฉด NULL)
key ; query์— ์‚ฌ์šฉ๋œ index ํ‘œ์‹œ. (NULL if no index was selected)
key_len = the length of the index MySQL decided to use.
ref = the value being compared to the key to decide whether to select rows.
rows = an estimate of the number of rows from this table MySQL will read to generate the
results of the query. You can work out how many rows will be read overall by multiplying the
rows' values together. This gives a basic benchmark for how fast the query will run.
Extra = ์ถ”๊ฐ€์ •๋ณด (์˜ˆ: Using index means that MySQL can retrieve the result of the query
completely from an index without reading data from the table.)
(ํ•ด์„ ๋’ท์žฅ)
198
โ€“
โ€“
Employee table์—์„œ์˜ join type ALL; ๋ชจ๋“  row๋“ค์ด scan๋  ๊ฒƒ์„ ์˜๋ฏธ.๏ƒ  table์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋งŽ์œผ๋ฉด ๋Šฆ์–ด์งˆ๊ฒƒ. ์‹ค์ œ
๋กœ join type ALL์€ ์ตœ์•…์˜ ๊ฒฝ์šฐ. (๏ƒŸ typically if a table has no useful index.) (ํ•ด๊ฒฐ์ฑ…) add an index.
Department์— ํ•ด๋‹น๋˜๋Š” row์˜ join type eq_ref; (์˜๋ฏธ) a single row will be read from the department table
for each row in the employee table. (= one of the best types.) The only better values for type are system
and const, (์˜๋ฏธ: table์ด ์˜ค์ง ํ•˜๋‚˜์˜ matching row๋ฅผ ๊ฐ€์ง€๋ฉฐ can effectively be treated as a constant. )
โ€“ (other possible values for type: )
โ€ข ref ; All rows with matching index values will be read from the table. (eq_ref ๋‹ค์Œ์˜
second best)๋กœ์„œ non-unique key ์ƒํƒœ์ผ ๋•Œ์ž„.
โ€ข range ; (์˜๋ฏธ) all rows in a particular range will be read from the table. (eq_ref ๋˜๋Š” ref
๋งŒ๋„ ๋ชป ํ•จ)
โ€ข index ; (์˜๋ฏธ) the complete index will be scanned. (ALL๋ณด๋‹ค๋Š” ์ข‹์ง€๋งŒ ์•ž์„œ์˜ ๋‹ค๋ฅธ ๊ฒƒ๋ณด๋‹ค
๋ชปํ•จ.) This is preferable to scanning the complete table, but is far from ideal.
โ€ข possible_keys and key ; The department table has one option: PRIMARY. Employee
table has the value NULL in both of these columns, (์˜๋ฏธ: there's no key to use and
therefore no key will be used. = a strong hint that we should be adding another index!
โ€“ ์ด ์ •๋ณด์— ๋”ฐ๋ผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€ index ์ƒ์„ฑ ๏ƒ 
create index ename_did on employee(name, departmentID);
โ€ข If we then rerun EXPLAIN, we get the following output:
+----+-------------+-------+---------+-------------------+---------------+-----------+---------------------+------+---------------+
| id | select_type | table | type
| possible_keys
| key
| key_len | ref
| rows | Extra
|
+----+-------------+-------+---------+-------------------+--------------+------------+---------------------+------+---------------+
| 1 | SIMPLE
|e
| index
| NULL
| ename_did |
85
| NULL
|
5 | Using index |
| 1 | SIMPLE
|d
| eq_ref | PRIMARY
| PRIMARY
|
4
| e.departmentID
|
1|
|
+----+-------------+------+----------+-------------------+---------------+----------+----------------------+------+---------------+
2 rows in set (0.00 sec)
โ€ข /* employee์˜ type์€ index (๏ƒŸ ์ด์ œ ์ ํ•ฉํ•œ index๋ฅผ ๊ฐ€์ง€๋ฏ€๋กœ) The new index is listed as
a possible key, but it is not actually being used. Under Extra you will see that only the
index for this table is used, rather than the table itself. This should be slightly faster.
โ€ข (EXPLAIN ; query์†๋„์ฆ์ง„์„ ์œ„ํ•ด index๋ฅผ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ• ์ง€ ์•Œ๋ ค ์คŒ.)
199
Understanding MySQL's Built-In
Query Optimization
โ€ข
MySQL applies many optimization rules to queries.
โ€“ MySQL uses its estimated number of rows (as shown in EXPLAIN) to work
out the best order in which to join tables. If you notice that its estimate is
off, you may want to experiment with using a STRAIGHT JOIN to force the
table order. Benchmarking before and after cases will tell you whether you
are helping or hindering.
โ€“ To choose an index, MySQL looks for the most relevant index that spans
less than 30% of the rows. If it can't find an index fitting these criteria, the
table will be scanned instead. (This was what happened in the EXPLAIN
query we looked at earlier, after we added the new index.)
โ€“ Expressions in WHERE clauses are optimized in a similar way to the way
many programming compilers optimize expressions. For example,
unnecessary parentheses in expressions are removed. This is one reason
you should feel free to make your queries more readable with parentheses.
โ€“ If a query can be resolved wholly from indexes, it will be done without any
reference to the actual rows in the table. Evaluation of COUNT(*) is also
evaluated without reading or counting the rows in a table because this data
is stored separately.
โ€ข
Manual, source code ๋ถ„์„ํ•  ๊ฒƒ !!
200
Optimization Tips
โ€ข Add indexes.
โ€“ Chapter 18, "Optimizing Your Database."
โ€“ Remember though that although an appropriate index might
speed up operations that need to find data in the table, keeping
indexes up-to-date increases the time required to write data. Do
not add indexes that will not be used.
โ€ข Use ANALYZE TABLE.
โ€“ (See Chapter 18 for syntax.)
โ€“ This updates the information MySQL stores about key distribution.
This information is used to decide the order in which tables are
joined. If MySQL seems to be joining your tables in a strange
order, try ANALYZE TABLE.
โ€ข Use OPTIMIZE TABLE.
โ€“ (See Chapter 18 for syntax.)
โ€“ This defragments the table storage, sorts the indexes, and
updates the table statistics as used by the query optimizer.
201