MySQL Innodb 저장 구조 및 저장 Null 값 용법 상세 설명
표 공간:INNODB 의 모든 데 이 터 는 표 공간 에 존재 합 니 다(공유 표 공간).innodb 를 열 면file_per_table,모든 표 의 데 이 터 는 하나의 표 공간 에 저 장 됩 니 다(표 공간 을 독점 합 니 다).
테이블 공간 은 데이터,색인,캐 시 삽입,데이터 사전 을 포함 합 니 다.공유 표 공간 은 Undo 정보(<물리 공간 상>을 회수 하지 않 음),더 블 캐 시 정보,사무 정보 등 을 포함한다.
세그먼트(segment):표 공간 을 구성 하고 구역 으로 구성 합 니 다.
구역(extent):64 개의 연속 페이지 로 구성 되 어 있 습 니 다.페이지 당 16K,총 1M.빅 데이터 세그먼트 에 대해 서 는 마지막 마다 4 개 구역 을 신청 할 수 있다.
페이지(page):INNODB 디스크 관리 단위 로 줄 로 구성 되 어 있 습 니 다.
줄(row):사무 ID,스크롤 백 포인터,열 정보 등 을 포함 합 니 다.
목적 1:
표 공간의 각 페이지 의 정보 와 넘 치 는 줄 데이터 에 저 장 된 정 보 를 알 아 보 세 요.이 책의 저자 장 승 요 를 통 해 작 성 된 도구:http://code.google.com/p/david-mysql-tools/source/browse/trunk/py_innodb_page_type/
3 개의 스 크 립 트:
py_innodb_page_info.py
View Code
#! /usr/bin/env python
#encoding=utf-8
import mylib
from sys import argv
from mylib import myargv
if __name__ == '__main__':
myargv = myargv(argv)
if myargv.parse_cmdline() == 0:
pass
else:
mylib.get_innodb_page_type(myargv)
mylib.py
View Code
encoding=utf-8
import os
import include
from include import *
TABLESPACE_NAME='D:\\mysql_data\\test\\t.ibd'
VARIABLE_FIELD_COUNT = 1
NULL_FIELD_COUNT = 0
class myargv(object):
def __init__(self, argv):
self.argv = argv
self.parms = {}
self.tablespace = ''
def parse_cmdline(self):
argv = self.argv
if len(argv) == 1:
print 'Usage: python py_innodb_page_info.py [OPTIONS] tablespace_file'
print 'For more options, use python py_innodb_page_info.py -h'
return 0
while argv:
if argv[0][0] == '-':
if argv[0][1] == 'h':
self.parms[argv[0]] = ''
argv = argv[1:]
break
if argv[0][1] == 'v':
self.parms[argv[0]] = ''
argv = argv[1:]
else:
self.parms[argv[0]] = argv[1]
argv = argv[2:]
else:
self.tablespace = argv[0]
argv = argv[1:]
if self.parms.has_key('-h'):
print 'Get InnoDB Page Info'
print 'Usage: python py_innodb_page_info.py [OPTIONS] tablespace_file
'
print 'The following options may be given as the first argument:'
print '-h help '
print '-o output put the result to file'
print '-t number thread to anayle the tablespace file'
print '-v verbose mode'
return 0
return 1
def mach_read_from_n(page,start_offset,length):
ret = page[start_offset:start_offset+length]
return ret.encode('hex')
def get_innodb_page_type(myargv):
f=file(myargv.tablespace,'rb')
fsize = os.path.getsize(f.name)/INNODB_PAGE_SIZE
ret = {}
for i in range(fsize):
page = f.read(INNODB_PAGE_SIZE)
page_offset = mach_read_from_n(page,FIL_PAGE_OFFSET,4)
page_type = mach_read_from_n(page,FIL_PAGE_TYPE,2)
if myargv.parms.has_key('-v'):
if page_type == '45bf':
page_level = mach_read_from_n(page,FIL_PAGE_DATA+PAGE_LEVEL,2)
print "page offset %s, page type <%s>, page level <%s>"%(page_offset,innodb_page_type[page_type],page_level)
else:
print "page offset %s, page type <%s>"%(page_offset,innodb_page_type[page_type])
if not ret.has_key(page_type):
ret[page_type] = 1
else:
ret[page_type] = ret[page_type] + 1
print "Total number of page: %d:"%fsize
for type in ret:
print "%s: %s"%(innodb_page_type[type],ret[type])
include.py
View Code
#encoding=utf-8
INNODB_PAGE_SIZE = 16*1024*1024
# Start of the data on the page
FIL_PAGE_DATA = 38
FIL_PAGE_OFFSET = 4 # page offset inside space
FIL_PAGE_TYPE = 24 # File page type
# Types of an undo log segment */
TRX_UNDO_INSERT = 1
TRX_UNDO_UPDATE = 2
# On a page of any file segment, data may be put starting from this offset
FSEG_PAGE_DATA = FIL_PAGE_DATA
# The offset of the undo log page header on pages of the undo log
TRX_UNDO_PAGE_HDR = FSEG_PAGE_DATA
PAGE_LEVEL = 26 #level of the node in an index tree; the leaf level is the level 0 */
innodb_page_type={
'0000':u'Freshly Allocated Page',
'0002':u'Undo Log Page',
'0003':u'File Segment inode',
'0004':u'Insert Buffer Free List',
'0005':u'Insert Buffer Bitmap',
'0006':u'System Page',
'0007':u'Transaction system Page',
'0008':u'File Space Header',
'0009':u' ',
'000a':u'Uncompressed BLOB Page',
'000b':u'1st compressed BLOB Page',
'000c':u'Subsequent compressed BLOB Page',
'45bf':u'B-tree Node'
}
innodb_page_direction={
'0000': 'Unknown(0x0000)',
'0001': 'Page Left',
'0002': 'Page Right',
'0003': 'Page Same Rec',
'0004': 'Page Same Page',
'0005': 'Page No Direction',
'ffff': 'Unkown2(0xffff)'
}
INNODB_PAGE_SIZE=1024*16 # InnoDB Page 16K
테스트 1:
root@localhost : test 02:26:13>create table tt(id int auto_increment,name varchar(10),age int,address varchar(20),primary key (id))engine=innodb;
Query OK, 0 rows affected (0.17 sec)
root@zhoujy:/var/lib/mysql/test# ls -lh tt.ibd
-rw-rw---- 1 mysql mysql 96K 2012-10-17 14:26 tt.ibd
ibd 보기:
root@zhoujy:/home/zhoujy/jiaoben/read_ibd# python py_innodb_page_info.py /var/lib/mysql/test/tt.ibd -v
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0000> ---
page offset 00000000, page type <Freshly Allocated Page>
page offset 00000000, page type <Freshly Allocated Page>
Total number of page: 6:
Freshly Allocated Page: 2
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 1
File Segment inode: 1
설명:총 페이지 수:총 페이지 수
새로 할 당 된 페이지:사용 가능 한 페이지
Buffer Bitmap 삽입:캐 시 비트 맵 페이지 삽입
Buffer 무료 목록 삽입:캐 시 남 은 목록 페이지 삽입
B-tree 노드:데이터 페이지
Uncompressed BLOB 페이지:바 이 너 리 대상 페이지,넘 치 는 줄 을 저장 하 는 페이지,즉 넘 치 는 페이지
위 에서 얻 은 정 보 는 표 초기 화 크기 가 96K 이 고 Total number of page*16 에서 얻 은 것 입 니 다.데이터 페이지 1 개,사용 가능 한 페이지 2 개.
root@localhost : test 02:42:58>insert into tt values(name,age,address) values('aaa',23,'HZZZ');
의혹:왜 신청 구역 이 없 습 니까?구역 은 64 개의 연속 페이지 이 고 크기 는 1M 이다.그럼 시계 크기 도 최소 1m 는 돼 야 지.하지만 지금 은 96K(기본 값)밖 에 없다.각 단락 이 시 작 될 때 32 페이지 크기 의 조각 페이지 에 데 이 터 를 저장 하고 사용 하기 때문이다.완 료 된 후에 야 64 페이지 의 연속 신청 으로 최대 4 개 구역 을 신청 하여 데이터 의 순 서 를 보증 할 수 있다.여기 서 표 크기 증 가 는 최소 64 페이지 크기 의 공간 에 따라 증가 하 는 것 으로 나 타 났 다.즉,1M 증가 이다.
인증:
데 이 터 를 채 우 고 이 32 개의 조각 페이지 를 채 우 고 32*16=512 K.1M 이상 의 공간 을 신청 할 수 있 는 지 살 펴 보 자.
View Code
root@zhoujy:/home/zhoujy/jiaoben/read_ibd# ls -lh /var/lib/mysql/test/tt.ibd
-rw-rw---- 1 mysql mysql 576K 2012-10-17 15:30 /var/lib/mysql/test/tt.ibd
root@zhoujy:/home/zhoujy/jiaoben/read_ibd# python py_innodb_page_info.py /var/lib/mysql/test/tt.ibd -v
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0001>
page offset 00000004, page type <B-tree Node>, page level <0000>
page offset 00000005, page type <B-tree Node>, page level <0000>
page offset 00000006, page type <B-tree Node>, page level <0000>
page offset 00000007, page type <B-tree Node>, page level <0000>
page offset 00000008, page type <B-tree Node>, page level <0000>
page offset 00000009, page type <B-tree Node>, page level <0000>
page offset 0000000a, page type <B-tree Node>, page level <0000>
page offset 0000000b, page type <B-tree Node>, page level <0000>
page offset 0000000c, page type <B-tree Node>, page level <0000>
page offset 0000000d, page type <B-tree Node>, page level <0000>
page offset 0000000e, page type <B-tree Node>, page level <0000>
page offset 0000000f, page type <B-tree Node>, page level <0000>
page offset 00000010, page type <B-tree Node>, page level <0000>
page offset 00000011, page type <B-tree Node>, page level <0000>
page offset 00000012, page type <B-tree Node>, page level <0000>
page offset 00000013, page type <B-tree Node>, page level <0000>
page offset 00000014, page type <B-tree Node>, page level <0000>
page offset 00000015, page type <B-tree Node>, page level <0000>
page offset 00000016, page type <B-tree Node>, page level <0000>
page offset 00000017, page type <B-tree Node>, page level <0000>
page offset 00000018, page type <B-tree Node>, page level <0000>
page offset 00000019, page type <B-tree Node>, page level <0000>
page offset 0000001a, page type <B-tree Node>, page level <0000>
page offset 0000001b, page type <B-tree Node>, page level <0000>
page offset 0000001c, page type <B-tree Node>, page level <0000>
page offset 0000001d, page type <B-tree Node>, page level <0000>
page offset 0000001e, page type <B-tree Node>, page level <0000>
page offset 0000001f, page type <B-tree Node>, page level <0000>
page offset 00000020, page type <B-tree Node>, page level <0000>
page offset 00000021, page type <B-tree Node>, page level <0000>
page offset 00000022, page type <B-tree Node>, page level <0000>
page offset 00000023, page type <B-tree Node>, page level <0000>
Total number of page: 36:
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 33
File Segment inode: 1
"추가"페이지:4 개page offset 00000000,page type
page offset 0000001,page type<삽입 버퍼 비트 맵>:캐 시 비트 맵 페이지 삽입
page offset 0000002,page type
page offset 0000003,page type
조각 페이지:32 개
page type
총 36 페이지,ibd 크기 576 K 의 유래:32*16=512 K(조각 페이지)+4*16=64(추가 페이지),여기 서 다시 삽입 하려 면 최소 1M 페이지 를 신청 해 야 합 니 다.
root@zhoujy:/home/zhoujy/jiaoben/read_ibd# ls -lh /var/lib/mysql/test/tt.ibd
-rw-rw---- 1 mysql mysql 2.0M 2012-10-17 16:10 /var/lib/mysql/test/tt.ibd
root@zhoujy:/home/zhoujy/jiaoben/read_ibd# python py_innodb_page_info.py /var/lib/mysql/test/tt.ibd
Total number of page: 128:
Freshly Allocated Page: 91
Insert Buffer Bitmap: 1
File Space Header: 1
B-tree Node: 34
File Segment inode: 1
페이지 는 36 에서 128 로 뛰 었 다.이미 32 개의 조각 페이지 를 다 썼 기 때문에 새로운 페이지 는 구역 방식 으로 공간 신청 을 할 것 이다.정보 에서 사용 가능 한 페이지 가 많은 것 을 보 았 는데,바로 이 점 을 설명 한다.▲넘 치 는 줄 데이터 저장:INNODB 저장 엔진 은 페이지 당 최소 두 줄 의 기록 이 있 는 색인 조직 이기 때문에 페이지 에 한 줄 의 기록 만 저장 할 수 있다 면 INNODB 는 자동 으로 넘 치 는 페이지 에 줄 데 이 터 를 넣 습 니 다.넘 침 줄 이 발생 했 을 때 실제 데 이 터 는 BLOB 페이지 에 저장 되 고 데이터 페이지 는 데이터 의 이전 768 바이트(오래된 파일 형식)만 저장 되 며 새로운 파일 형식(Barracuda)은 완전히 넘 침 방식 으로 데이터 페이지 는 20 바이트 의 지침 만 저장 되 며 BLOB 도 있 는 데 이 터 를 저장 합 니 다.어떻게 표 에 넘 치 는 줄 의 데 이 터 를 봅 니까?
root@localhost : test 04:52:34>create table t1 (id int,name varchar(10),memo varchar(8000))engine =innodb default charset utf8;
Query OK, 0 rows affected (0.16 sec)
root@localhost : test 04:53:10>insert into t1 values(1,'zjy',repeat(' ',8000));
Query OK, 1 row affected (0.00 sec)
ibd 보기:
root@zhoujy:/home/zhoujy/jiaoben/read_ibd# python py_innodb_page_info.py /var/lib/mysql/test/t1.ibd -v
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0000>
page offset 00000004, page type <Uncompressed BLOB Page>
page offset 00000005, page type <Uncompressed BLOB Page>
Total number of page: 6:
Insert Buffer Bitmap: 1
Uncompressed BLOB Page: 2
File Space Header: 1
B-tree Node: 1
File Segment inode: 1
정보 에서 보 듯 이 방금 삽 입 된 한 줄 의 기록 이 넘 쳐 2 개의 BLOB 페이지 에 저장 되 었 습 니 다(
root@localhost : test 05:08:39>create table t2 (id int,name varchar(1000),address varchar(512),company varchar(200),xx varchar(512),memo varchar(512),dem varchar(1000))engine =innodb default charset utf8;
Query OK, 0 rows affected (0.17 sec)
root@localhost : test 05:08:43>insert into t2 values(1,repeat(' ',1000),repeat(' ',500),repeat(' ',500),repeat(' ',500),repeat(' ',500),repeat(' a',500));
1000+500+500+500+500+500=3500*3>8000 바이트;길드 넘 침:
root@zhoujy:/home/zhoujy/jiaoben/read_ibd# python py_innodb_page_info.py /var/lib/mysql/test/t2.ibd -v
page offset 00000000, page type <File Space Header>
page offset 00000001, page type <Insert Buffer Bitmap>
page offset 00000002, page type <File Segment inode>
page offset 00000003, page type <B-tree Node>, page level <0000>
page offset 00000004, page type <Uncompressed BLOB Page>
page offset 00000000, page type <Freshly Allocated Page>
Total number of page: 6:
Insert Buffer Bitmap: 1
Freshly Allocated Page: 1
File Segment inode: 1
B-tree Node: 1
File Space Header: 1
Uncompressed BLOB Page: 1
root@zhoujy:/home/zhoujy/jiaoben/read_ibd# hexdump -C -v /var/lib/mysql/test/t1.ibd > t1.txt
ibd 보기:
View Code
3082 0000c090 00 32 01 10 80 00 00 01 7a 6a 79 e6 88 91 e6 88 |.2......zjy.....|
3083 0000c0a0 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3084 0000c0b0 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3085 0000c0c0 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3086 0000c0d0 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3087 0000c0e0 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3088 0000c0f0 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3089 0000c100 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3090 0000c110 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3091 0000c120 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3092 0000c130 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3093 0000c140 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3094 0000c150 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3095 0000c160 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3096 0000c170 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3097 0000c180 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3098 0000c190 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3099 0000c1a0 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3100 0000c1b0 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3101 0000c1c0 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3102 0000c1d0 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3103 0000c1e0 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3104 0000c1f0 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3105 0000c200 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3106 0000c210 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3107 0000c220 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3108 0000c230 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3109 0000c240 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3110 0000c250 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3111 0000c260 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3112 0000c270 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3113 0000c280 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3114 0000c290 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3115 0000c2a0 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3116 0000c2b0 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3117 0000c2c0 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3118 0000c2d0 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3119 0000c2e0 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3120 0000c2f0 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3121 0000c300 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3122 0000c310 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3123 0000c320 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3124 0000c330 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3125 0000c340 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3126 0000c350 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3127 0000c360 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 |................|
3128 0000c370 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 |................|
3129 0000c380 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 88 91 e6 |................|
3130 0000c390 88 91 e6 88 91 e6 88 91 e6 88 91 00 00 02 1c 00 |................|
텍스트 중 마침 48 줄 이 고 줄 당 16 바이트 입 니 다.48*16=768 바이트,데이터 페이지 는 데이터 만 저장 하 는 이전 768 바이트(오래된 파일 형식)를 마침 검증 했다.총화 1:
위의 정 보 를 통 해 ibd 표 공간의 각 페이지 의 분포 와 이용 정보 와 표 공간의 크기 가 증가 하 는 보폭 을 뚜렷하게 알 수 있다.특히 주의해 야 할 것 은 넘 치 는 줄 입 니 다.한 페이지 에 최소 2 줄 의 데 이 터 를 포함 하고 있 습 니 다.페이지 에 저 장 된 줄 이 많 을 수록 성능 이 좋 습 니 다.
************************************
************************************
목적 2:
표 공간 에 데 이 터 를 어떻게 저장 하 는 지,그리고 NULL 값 에 대한 저장 을 알 아 봅 니 다.
테스트 2:
테스트 전에 INNODB 의 저장 형식 부터 알 아 보기(rowformat)。오래된 형식(Antelope):컴 팩 트<기본 값>,Redumdant;새 형식(Barracuda):Compressed,Dynamic.
기본 저장 형식 에 대한 포인터 테스트 입 니 다.
Compact 행 기록 방식 은 다음 과 같 습 니 다.
| (1~2 )|NULL (1 )| (5 )|RowID(6 )| ID(6 )| (7 )|
위의 정 보 는'NULL 플래그 비트'를 제외 하고[표 의 모든 필드 를 NOT NULL 로 정의 합 니 다],'RowID'[표 에 메 인 키 가 있 습 니 다],'길 어 지 는 필드 길이 목록'[길 어 지 는 필드 없 음]이 존재 하지 않 을 수도 있 고 다른 정보 가 나타 납 니 다.따라서 한 줄 의 데 이 터 는 열 데이터 가 차지 하 는 필드 를 제외 하고 18 바이트 가 추가 로 필요 합 니 다.1:필드 전체 NULL
mysql> create table mytest(t1 varchar(10),t2 varchar(10),t3 varchar(10) ,t4 varchar(10))engine=innodb charset = latin1 row_format=compact;
Query OK, 0 rows affected (0.08 sec)
mysql> insert into mytest values('a','bb','bb','ccc');
Query OK, 1 row affected (0.02 sec)
mysql> insert into mytest values('a','ee','ee','fff');
Query OK, 1 row affected (0.01 sec)
mysql> insert into mytest values('a',NULL,NULL,'fff');
Query OK, 1 row affected (0.00 sec)
테스트 데이터 준비 후 셸 명령 실행:
root@zhoujy:/usr/local/mysql/test# hexdump -C -v mytest.ibd > /home/zhoujy/mytest.txt
my test.txt 파일 을 열 어 supremum 줄 을 찾 습 니 다:
0000c070 73 75 70 72 65 6d 75 6d 03 02 02 01 00 00 00 10 |supremum........| -----------> ,16
0000c080 00 25 00 00 00 03 b9 00 00 00 00 02 49 01 82 00 |.%..........I...|
0000c090 00 01 4a 01 10 61 62 62 62 62 63 63 63 03 02 02 |..J..abbbbccc...|
0000c0a0 01 00 00 00 18 00 23 00 00 00 03 b9 01 00 00 00 |......#.........|
0000c0b0 02 49 02 83 00 00 01 4b 01 10 61 65 65 65 65 66 |.I.....K..aeeeef|
0000c0c0 66 66 03 01 06 00 00 20 ff a6 00 00 00 03 b9 02 |ff..... ........|
0000c0d0 00 00 00 02 49 03 84 00 00 01 4c 01 10 61 66 66 |....I.....L..aff|
0000c0e0 66 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |f...............|
설명:첫 번 째 줄 데이터:
03 02 02 01/*필드 가 길 어 집 니 다*/-표 의 4 개의 필드 유형 은 varchar 이 고 NULL 데이터 가 없 으 며 각 필드 군 은 255 보다 작 습 니 다.
00/*NULL 표지 위치,첫 줄 에 null 데이터 가 없습니다*/
00 00 10 00 25/*헤드 정보 기록,5 바이트 고정*/
00 00 00 03 b9 00/*RowID,6 바이트 고정,표 에 홈 키 없 음*/
00 00 00 02 49 01/*사무 ID,6 바이트 고정*/
82 00 00 01 4a 01 10/*스크롤 백 포인터,7 바이트 고정*/
61 62 62 62 63 63 63/*열의 데이터*/
두 번 째 줄 데 이 터 는 첫 번 째 줄 데이터 와 같 습 니 다(색상 일치).
세 번 째 줄 데이터(NULL 값 이 있 음)와 첫 번 째 줄 의 설명 색상 이 대응 하 는 차이 점:
03 02 02 01 VS 03 01 ---------- NULL , 。
61 62 62 62 62 63 63 63 VS 61 66 66 66 --------- NULL ,
결론:NULL 일 때 필드 목록 이 길 어 지면 저장 공간 을 차지 하지 않 습 니 다.NULL 값 은 저장 되 지 않 고 공간 을 차지 하지 않 지만 표지 위치(한 줄 한 줄)가 필요 합 니 다.2:필드 전체 NOT NULL
mysql> create table mytest(t1 varchar(10) NOT NULL,t2 varchar(10) NOT NULL,t3 varchar(10) NOT NULL,t4 varchar(10) NOT NULL)engine=innodb charset = latin1 row_format=compact;
Query OK, 0 rows affected (0.03 sec)
mysql> insert into mytest values('a','bb','bb','ccc');
Query OK, 1 row affected (0.01 sec)
mysql> insert into mytest values('a','ee','ee','fff');
Query OK, 1 row affected (0.01 sec)
mysql> insert into mytest values('a',NULL,NULL,'fff');
ERROR 1048 (23000): Column 't2' cannot be null
절차 가 위 와 마찬가지 로 얻 은 ibd 의 결 과 는:
0000c070 73 75 70 72 65 6d 75 6d 03 02 02 01 00 00 10 00 |supremum........|
0000c080 24 00 00 00 03 b9 03 00 00 00 02 49 07 87 00 00 |$..........I....|
0000c090 01 4f 01 10 61 62 62 62 62 63 63 63 03 02 02 01 |.O..abbbbccc....|
0000c0a0 00 00 18 ff cb 00 00 00 03 b9 04 00 00 00 02 49 |...............I|
0000c0b0 08 88 00 00 01 50 01 10 61 65 65 65 65 66 66 66 |.....P..aeeeefff|
위 와 비교 해 보면 NULL 의 표지 위치 정보 가 빠 진 것 을 발견 했다.결론:NULL 값 은 줄 당 1 바이트 의 크기 를 저장 할 수 있 는 추가 공간 이 있 습 니 다.같은 데이터 의 표 에 대해 필드 에 NULL 값 이 있 는 표 는 NOT NULL 보다 큽 니 다.
3:1 개의 NULL 과 1 개의 데이터:
mysql> create table mytest(t1 varchar(10) NOT NULL,t2 varchar(10) NOT NULL DEFAULT '',t3 varchar(10) NOT NULL ,t4 varchar(10))engine=innodb charset = latin1 row_format=compact;
Query OK, 0 rows affected (0.02 sec)
mysql> insert into mytest(t1,t2) values('A','BB');
Query OK, 1 row affected, 1 warning (0.01 sec)
절차 가 위 와 마찬가지 로 얻 은 ibd 의 결 과 는:
0000c070 73 75 70 72 65 6d 75 6d 00 02 01 01 00 00 10 ff |supremum........|
0000c080 ef 00 00 00 43 b9 03 00 00 00 02 4a 15 90 00 00 |....C......J....|
0000c090 01 c2 01 10 41 42 42 00 00 00 00 00 00 00 00 00 |....ABB.........|
위의 두 가지 차이 점 은 주로 길 어 지 는 목록 과 열 데이터 에 있 습 니 다.결론:열 데이터 정보 에서 NULL 데이터 와'데 이 터 는 그 어떠한 공간 도 차지 하지 않 는 다 는 것 을 나타 낸다.길 어 지 는 필드 목록 에 대한 정 보 는'데 이 터 는 그 어떠한 저장 공간 도 차지 할 필요 가 없 지만 길 어 지 는 필드 목록 에서 한 글자 절 을 차지 해 야 한다'는 것 과 비교 해 보면 NULL 값 은 차지 할 필요 가 없다'는 것 을 알 수 있다.다만 NULL 은 추가 로 표 시 된 위치 가 있 기 때문에 최적화 설 이 있 습 니 다."데이터베이스 시트 에 NOT NULL 을 설정 할 수 있 는 것 은 가능 한 한 NOT NULL 로 설정 합 니 다.NULL 이 필요 하지 않 는 한"여기 서 증 명 됐 습 니 다.
위의 테스트 는 모두 VARCHAR 의 길 어 지 는 유형 을 겨냥 한 것 인 데 CHAR 에 대해 서 는?
CHAR 테스트:
root@localhost : test 10:33:35>create table mytest(t1 char(10),t2 char(10),t3 char(10) ,t4 char(10))engine=innodb charset = latin1 row_format=compact;Query OK, 0 rows affected (0.16 sec)
root@localhost : test 10:33:59>insert into mytest values('a','bb','bb','ccc');
Query OK, 1 row affected (0.00 sec)
root@localhost : test 10:34:09>insert into mytest values('a','ee','ee','fff');
Query OK, 1 row affected (0.00 sec)
root@localhost : test 10:34:19>insert into mytest values('a',NULL,NULL,'fff');
Query OK, 1 row affected (0.00 sec)
ibd 에서 생 성 된 파일 열기:
0000c060 02 00 1b 69 6e 66 69 6d 75 6d 00 04 00 0b 00 00 |...infimum......|
0000c070 73 75 70 72 65 6d 75 6d 00 00 00 10 00 41 00 00 |supremum.....A..|
0000c080 00 0a f5 00 00 00 00 81 2d 07 80 00 00 00 32 01 |........-.....2.|
0000c090 10 61 20 20 20 20 20 20 20 20 20 62 62 20 20 20 |.a bb |
0000c0a0 20 20 20 20 20 62 62 20 20 20 20 20 20 20 20 63 | bb c|
0000c0b0 63 63 20 20 20 20 20 20 20 00 00 00 18 00 41 00 |cc .....A.|
0000c0c0 00 00 0a f5 01 00 00 00 81 2d 08 80 00 00 00 32 |.........-.....2|
0000c0d0 01 10 61 20 20 20 20 20 20 20 20 20 65 65 20 20 |..a ee |
0000c0e0 20 20 20 20 20 20 65 65 20 20 20 20 20 20 20 20 | ee |
0000c0f0 66 66 66 20 20 20 20 20 20 20 06 00 00 20 ff 70 |fff ... .p|
0000c100 00 00 00 0a f5 02 00 00 00 81 2d 09 80 00 00 00 |..........-.....|
0000c110 32 01 10 61 20 20 20 20 20 20 20 20 20 66 66 66 |2..a fff|
0000c120 20 20 20 20 20 20 20 00 00 00 00 00 00 00 00 00 | .........|
1 의 varchar 와 비교 해 보면 길 어 지 는 필드 목록 이 적 지만 char 에 게 는 고정 길이 로 저장 해 야 하 며 고정 길이 가 저장 되 지 않 아 도 채 워 집 니 다.예:20;그리고 NULL 값 도 저장 공간 을 차지 할 필요 가 없습니다.혼합(varchar,char):
root@localhost : test 11:21:48>create table mytest(t1 int,t2 char(10),t3 varchar(10) ,t4 char(10))engine=innodb charset = latin1 row_format=compact;
Query OK, 0 rows affected (0.17 sec)
root@localhost : test 11:21:50>insert into mytest values(1,'a','b','c');
Query OK, 1 row affected (0.00 sec)
root@localhost : test 11:22:06>insert into mytest values(11,'aa','bb','cc');
Query OK, 1 row affected (0.00 sec)
위의 표 구조 에서 볼 수 있다.1,길 어 지 는 필드 목록 길이:1
2,NULL 표지 위치:1
3,기록 헤더 정보:5
4,RowID:6
5,사무 ID:6
6,스크롤 백 포인터:7
idb 의 정보:
0000c070 73 75 70 72 65 6d 75 6d 01 00 00 00 10 00 33 00 |supremum......3.|
0000c080 00 00 0a f5 07 00 00 00 81 2d 1a 80 00 00 00 32 |.........-.....2|
0000c090 01 10 80 00 00 01 61 20 20 20 20 20 20 20 20 20 |......a |
0000c0a0 62 63 20 20 20 20 20 20 20 20 20 02 00 00 00 18 |bc .....|
0000c0b0 ff be 00 00 00 0a f5 08 00 00 00 81 2d 1b 80 00 |............-...|
0000c0c0 00 00 32 01 10 80 00 00 0b 61 61 20 20 20 20 20 |..2......aa |
0000c0d0 20 20 20 62 62 63 63 20 20 20 20 20 20 20 20 00 | bbcc .|
위의 정 보 를 통 해 알 수 있 듯 이 표 에 varchar 필드 가 하나 밖 에 없 기 때문에 목록 길이 가 길 어 지 는 것 은:01 입 니 다.특히 주의해 야 할 것 은 각 열 데이터 에 저 장 된 정보:t1 필드 는 int 형식 으로 4 개의 바이트 크기 를 차지한다.첫 번 째 줄:8000 00 01 은 1 숫자 를 나타 낸다.두 번 째 줄:8000 00 0b 는 11 의 숫자 를 나타 낸다.select hex(11)=B],다른 것 은 위의 예 와 같 습 니 다.
위 에 있 는 것 은 모두 latin 1 단일 바이트 문자 집합 에 대한 설명 입 니 다.그러면 다 중 바이트 문자 집합 에 대한 상황 은 어 떻 습 니까?
root@localhost : test 11:52:10>create table mytest(id int auto_increment,t2 varchar(10),t3 varchar(10) ,t4 char(10),primary key(id))engine=innodb charset = utf8 row_format=compact;
Query OK, 0 rows affected (0.17 sec)
root@localhost : test 11:52:11>insert into mytest(t2,t3,t4) values('bb','bb','ccc');
Query OK, 1 row affected (0.00 sec)
root@localhost : test 11:55:34>insert into mytest(t2,t3,t4) values(' ',' ',' ');
Query OK, 1 row affected (0.00 sec)
ibd 정 보 는 다음 과 같 습 니 다.
0000c070 73 75 70 72 65 6d 75 6d 0a 02 02 00 00 00 10 00 |supremum........|
0000c080 28 80 00 00 01 00 00 00 81 2d 27 80 00 00 00 32 |(........-'....2|
0000c090 01 10 62 62 62 62 63 63 63 20 20 20 20 20 20 20 |..bbbbccc |
0000c0a0 0a 06 06 00 00 00 18 ff c7 80 00 00 02 00 00 00 |................|
0000c0b0 81 2d 28 80 00 00 00 32 01 10 e6 88 91 e4 bb ac |.-(....2........|
0000c0c0 e4 bb 96 e4 bb ac e6 88 91 e4 bb ac e7 9a 84 20 |............... |
시계 에 메 인 키 가 있어 서 ROWID(6 바이트)가 없어 졌어 요.특히 주의해 야 할 것 은:길 어 지 는 필드 목록 은 3?표 안에 있 는 varchar 형식의 열 은 두 개 밖 에 없 는데.테스트 결과 에 따 르 면 다 중 바이트 문자 집합 조건 에서 char 형식 은 가 변 길이 의 유형 으로 처리 되 고 그들의 줄 저장 소 는 거의 다 르 지 않 기 때문에 이것 은 길 어 지 는 목록 이 3 입 니 다.utf 8 문자 집합 이기 때문에 세 개의 바이트 를 차지 합 니 다.그래서 한 한자 가 한 페이지 에 세 바이트 의 공간 을 차지 했다("우리":e6 88 91 e4 bb ac).
데이터 열의 정보:
id 열의 1 값 은 8000 01 이 어야 합 니 다.왜 이것 은 00 32 01 10 을 표시 합 니까?그리고 모든 id 는 00 32 01 10 입 니 다.테스트 결과 id 가 홈 키 를 추가 할 때 id 의 4 바이트 길 이 는 모두 00 32 01 10 으로 표 시 된 것 으로 나 타 났 다.그렇지 않 으 면 앞의 예 에서 말 한 것 과 같이 select HEX(X)로 표시 합 니 다.
총괄 2:
위의 테스트 는 모두 COMPACT 저장 형식 을 기반 으로 합 니 다.varchar 든 char 든 NULL 값 은 저장 공간 을 차지 할 필요 가 없습니다.특히 주의해 야 할 것 은 Redumdant 의 기록 헤드 정 보 는 6 개의 고정 바이트 가 필요 하 다 는 것 이다.다 중 바이트 문자 집합의 조건 하에 서 CHAR 와 VARCHAR 의 줄 저장 소 는 기본적으로 차이 가 없다.
이 글 은 MySQL Innodb 저장 구조 와 Null 값 저장 용법 에 대한 상세 한 설명 입 니 다.MySQL Innodb 저장 구조 에 대해 더 많은 것 을 소개 합 니 다. Null 값 내용 을 저장 하려 면 이전 글 을 검색 하거나 아래 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Redash를 사용할 때 몰랐던 SQL을 쓰는 법을 배웠습니다.최근 redash에서 sql을 쓸 기회가 많고, 이런 쓰는 방법이 있었는지와 sql에 대해 공부를 다시하고 있기 때문에 배운 것을 여기에 씁니다. Redash란? 월별로 데이터를 표시하고 싶습니다 주별로 데이터를 표...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.