??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产福利在线,久久亚洲精华国产精华液,亚洲精品自拍偷拍http://www.aygfsteel.com/lijie250/zh-cnSat, 17 May 2025 12:20:58 GMTSat, 17 May 2025 12:20:58 GMT60MySql无限分类数据l构http://www.aygfsteel.com/lijie250/archive/2008/10/15/234227.htmljezzjezzWed, 15 Oct 2008 01:27:00 GMThttp://www.aygfsteel.com/lijie250/archive/2008/10/15/234227.htmlhttp://www.aygfsteel.com/lijie250/comments/234227.htmlhttp://www.aygfsteel.com/lijie250/archive/2008/10/15/234227.html#Feedback0http://www.aygfsteel.com/lijie250/comments/commentRss/234227.htmlhttp://www.aygfsteel.com/lijie250/services/trackbacks/234227.html 我们最常见最单的Ҏ是在MySql里ID ,parentID,nameQ?br /> 优点是简单,l构单?br /> ~点是效率不高,因ؓ每一ơ递归都要查询数据库,几百条数据库时就不是很快了!

存储树是一U常见的问题Q多U解x案。主要有两种ҎQ邻接表的模型,q修Ҏ前序遍历法?

我们探讨这两种Ҏ的节能等U的数据。我会用树从一个虚构的|上食品商店作ؓ一个例子。这食品商店l织光品类Q通过颜色和类型。这|看v来像q样Q?

下面我们用另外一U方法,q就是预排序遍历树算?modified preorder tree traversal algorithm) 
q种Ҏ大家可能接触的比较少Q初ơ用也不像上面的方法容易理解,但是׃q种Ҏ不用递归查询法Q有更高的查询效率?br /> 我们首先多U数据按照下面的方式dU怸Q在根节点Food的左侧写?nbsp;1 然后沿着q个树l向?nbsp;?nbsp;Fruit 的左侧写?nbsp;2 然后l箋前进Q沿着整个树的边缘l每一个节炚w标上左侧和右侧的数字。最后一个数字是标在Food 右侧?nbsp;18?nbsp;在下面的q张图中你可以看到整个标好了数字的多U结构。(没有看懂Q用你的手指指着数字?数到18明白怎么回事了。还不明白,再数一遍,注意Ud你的手指Q?nbsp;
q些数字标明了各个节点之间的关系Q?Red"的号??Q它?nbsp;"Food" 1-18 的子孙节炏V?nbsp;同样Q我们可以看?nbsp;所有左值大?和右值小?1的节?nbsp;都是"Fruit" 2-11 的子孙节?nbsp;

如图所C:


q样整个树状l构可以通过左右值来存储到数据库中。l之前,我们看一看下面整理过的数据表?nbsp;

注意Q由?left"?right"?nbsp;SQL中有Ҏ的意义,所以我们需要用"lft"?rgt"来表C左叛_Dc?nbsp;另外q种l构中不再需?parent"字段来表C树状结构。也是 说下面这L表结构就_了?nbsp;

SELECT * FROM tree WHERE lft BETWEEN 2 AND 11;


看到了吧Q只要一个查询就可以得到所有这些节炏Vؓ了能够像上面的递归函数那样昄整个树状l构Q我们还需要对q样的查询进行排序。用节点的左D行排序: 

SELECT * FROM tree WHERE lft BETWEEN 2 AND 11 ORDER BY lft ASC;

那么某个节点到底有多子孙节点呢Q很单,子孙L=(叛_?左?1)/2 
descendants = (right – left - 1) / 2 Q如果不是很清楚q个公式Q那去M书,我们在上数据l构写的很清楚!

d同一层次的节点的Ҏ如下Q?br />
LOCK TABLE nested_category WRITE;


SELECT @myRight := rgt FROM nested_category
WHERE name = 'Cherry';



UPDATE nested_category SET rgt = rgt + 2 WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft + 2 WHERE lft > @myRight;

INSERT INTO nested_category(name, lft, rgt) VALUES('Strawberry'@myRight + 1@myRight + 2);

UNLOCK TABLES;

d树的子节点的Ҏ如下Q?br />
LOCK TABLE nested_category WRITE;

SELECT @myLeft := lft FROM nested_category

WHERE name = 'Beef';

UPDATE nested_category SET rgt = rgt + 2 WHERE rgt > @myLeft;
UPDATE nested_category SET lft = lft + 2 WHERE lft > @myLeft;

INSERT INTO nested_category(name, lft, rgt) VALUES('charqui'@myLeft + 1@myLeft + 2);

UNLOCK TABLES;

每次插入节点之后都可以用以下SQLq行查看验证Q?br />
SELECT CONCAT( REPEAT( ' ', (COUNT(parent.name) - 1) ), node.name) AS name
FROM nested_category AS node,
nested_category 
AS parent
WHERE node.lft BETWEEN parent.lft AND parent.rgt
GROUP BY node.name
ORDER BY node.lft;

删除节点的方法,E微有点ȝ是有个中间变?如下Q?br />
LOCK TABLE nested_category WRITE;


SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
WHERE name = 'Cherry';


DELETE FROM nested_category WHERE lft BETWEEN @myLeft AND @myRight;


UPDATE nested_category SET rgt = rgt - @myWidth WHERE rgt > @myRight;
UPDATE nested_category SET lft = lft - @myWidth WHERE lft > @myRight;

UNLOCK TABLES;

 

q种方式是有点隄理解Q但是适合数据量很大规模用,查看所有的l构只需要两条SQL语句可以了Q在d节点和删除节点的时候略N烦,不过相对于效率来说还是值得的,q次发现让我发现了数据库l构真的很有用,但是我在学校学的树基本上都忘CQ这ơ遇到这个问题才应用到项目中Q?br />
参考文章:
http://dev.mysql.com/tech-resources/articles/hierarchical-data.html

http://www.sitepoint.com/article/hierarchical-data-database/3/

jezz 2008-10-15 09:27 发表评论
]]>
MySQL优化l验http://www.aygfsteel.com/lijie250/archive/2007/10/29/156786.htmljezzjezzMon, 29 Oct 2007 14:04:00 GMThttp://www.aygfsteel.com/lijie250/archive/2007/10/29/156786.htmlhttp://www.aygfsteel.com/lijie250/comments/156786.htmlhttp://www.aygfsteel.com/lijie250/archive/2007/10/29/156786.html#Feedback0http://www.aygfsteel.com/lijie250/comments/commentRss/156786.htmlhttp://www.aygfsteel.com/lijie250/services/trackbacks/156786.html同时在线讉K量l增?对于1G内存的服务器明显感觉到吃力严重时甚至每天都会L 或者时不时的服务器卡一?q个问题曄困扰了我半个多月MySQL使用是很具׾~性的法Q因此你通常能用很少的内存运行或lMySQL更多的被存以得到更好的性能?

安装好mysql后,配制文g应该?usr/local/mysql/share/mysql目录中,配制文g有几个,有my-huge.cnf my-medium.cnf my-large.cnf my-small.cnf,不同的流量的|站和不同配制的服务器环境,当然需要有不同的配制文件了?

一般的情况下,my-medium.cnfq个配制文gp满我们的大多需要;一般我们会把配|文件拷贝到/etc/my.cnf 只需要修改这个配|文件就可以了,使用mysqladmin variables extended-status –u root –p 可以看到目前的参敎ͼ有3个配|参数是最重要的,即key_buffer_size,query_cache_size,table_cache?

key_buffer_size只对MyISAM表v作用Q?

key_buffer_size指定索引~冲区的大小Q它军_索引处理的速度Q尤其是索引ȝ速度。一般我们设?6M,实际上稍微大一点的站点 q个数字是远q不够的Q通过查状态值Key_read_requests和Key_reads,可以知道key_buffer_size讄是否合理。比例key_reads / key_read_requests应该可能的低,臛_?:100Q?:1000更好Q上q状态值可以用SHOW STATUS LIKE ‘key_read%’获得Q?或者如果你装了phpmyadmin 可以通过服务器运行状态看?W者推荐用phpmyadmin理mysqlQ以下的状态值都是本人通过phpmyadmin获得的实例分?

q个服务器已l运行了20?

key_buffer_size – 128M
key_read_requests – 650759289
key_reads - 79112

比例接近1:8000 健康状况非常?

另外一个估计key_buffer_size的办法 把你|站数据库的每个表的索引所占空间大加h看看以此服务器ؓ?比较大的几个表烦引加h大概125M q个数字会随着表变大而变大?

?.0.1开始,MySQL提供了查询缓冲机制。用查询缓ԌMySQLSELECT语句和查询结果存攑֜~冲ZQ今后对于同LSELECT语句Q区分大写Q,直接从~冲Zdl果。根据MySQL用户手册Q用查询缓冲最多可以达?38%的效率?

通过调节以下几个参数可以知道query_cache_size讄得是否合?

Qcache inserts
Qcache hits
Qcache lowmem prunes
Qcache free blocks
Qcache total blocks

Qcache_lowmem_prunes的值非常大Q则表明l常出现~冲不够的情?同时Qcache_hits的值非常大Q则表明查询~冲使用非常频繁Q此旉要增加缓冲大Qcache_hits的g大,则表明你的查询重复率很低Q这U情况下使用查询~冲反而会影响效率Q那么可以考虑不用查询~冲。此外,在SELECT语句中加入SQL_NO_CACHE可以明确表示不用查询缓册Ӏ?

Qcache_free_blocksQ如果该值非常大Q则表明~冲Z片很多query_cache_type指定是否使用查询~冲

我设|?

query_cache_size = 32M
query_cache_type= 1

得到如下状态?

Qcache queries in cache 12737 表明目前~存的条?
Qcache inserts 20649006
Qcache hits 79060095  看来重复查询率还挺高?
Qcache lowmem prunes 617913 有这么多ơ出现缓存过低的情况
Qcache not cached 189896   
Qcache free memory 18573912  目前剩余~存I间
Qcache free blocks 5328 q个数字g有点大 片不少
Qcache total blocks 30953

如果内存允许32M应该要往上加?

table_cache指定表高速缓存的大小。每当MySQL讉K一个表Ӟ如果在表~冲Zq有I间Q该表就被打开q放入其中,q样可以更快地访问表内容。通过查峰值时间的状态值Open_tables和Opened_tablesQ可以决定是否需要增加table_cache的倹{如果你发现open_tables{于table_cacheQƈ且opened_tables在不断增长,那么你就需要增加table_cache的gQ上q状态值可以用SHOW STATUS LIKE ‘Open%tables’获得Q。注意,不能盲目地把table_cache讄成很大的倹{如果设|得太高Q可能会造成文g描述W不I从而造成性能不稳定或者连接失败?

对于?G内存的机器,推荐值是128Q?56?

W者设|table_cache = 256

得到以下状?

Open tables 256
Opened tables 9046

虽然open_tables已经{于table_cacheQ但是相对于服务器运行时间来?已经q行?0天,opened_tables的g非常低。因此,增加table_cache的值应该用处不大。如果运行了6个小时就出现上述?那就要考虑增大table_cache?

如果你不需要记?q制log 把q个功能xQ注意关掉以后就不能恢复出问题前的数据了Q需要您手动备䆾Q二q制日志包含所有更新数据的语句Q其目的是在恢复数据库时用它来把数据可能恢复到最后的状态。另外,如果做同步复? Replication )的话Q也需要用二q制日志传送修Ҏc?

log_bin指定日志文gQ如果不提供文g名,MySQL自׃生缺省文件名。MySQL会在文g名后面自动添加数字引Q每ơ启动服务时Q都会重新生成一个新的二q制文g。此外,使用log-bin-index可以指定索引文gQ用binlog-do-db可以指定记录的数据库Q用binlog-ignore-db可以指定不记录的数据库。注意的是:binlog-do-db和binlog-ignore-db一ơ只指定一个数据库Q指定多个数据库需要多个语句。而且QMySQL会将所有的数据库名U改成小写,在指定数据库时必d部用小写名字,否则不会起作用?

xq个功能只需要在他前面加??

#log-bin

开启慢查询日志( slow query log ) 慢查询日志对于跟t有问题的查询非常有用。它记录所有查qlong_query_time的查询,如果需要,q可以记录不使用索引的记录。下面是一个慢查询日志的例子:

开启慢查询日志Q需要设|参数log_slow_queries、long_query_times、log-queries-not-using-indexes?

log_slow_queries指定日志文gQ如果不提供文g名,MySQL自׃生缺省文件名。long_query_times指定慢查询的阈|~省?0U。log-queries-not-using-indexes?.1.0以后引入的参敎ͼ它指C录不使用索引的查询。笔者设|long_query_time=10

W者设|?

sort_buffer_size = 1M
max_connections=120
wait_timeout =120
back_log=100
read_buffer_size = 1M
thread_cache=32
interactive_timeout=120
thread_concurrency = 4

参数说明:

back_log

要求MySQL能有的连接数量。当主要MySQLU程在一个很短时间内得到非常多的q接hQ这pv作用Q然后主U程׃旉(管很短)查连接ƈ且启动一个新U程。back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。只有如果期望在一个短旉内有很多q接Q你需要增加它Q换句话_q值对到来的TCP/IPq接的侦听队列的大小。你的操作系l在q个队列大小上有它自q限制?Unix listen(2)pȝ调用的手册页应该有更多的l节。检查你的OS文扑ևq个变量的最大倹{试图设定back_log高于你的操作pȝ的限制将是无效的?

max_connections

q发q接数目最大,120 过q个值就会自动恢复,Z问题能自动解?

thread_cache

没找到具体说明,不过讄?2?20天才创徏?00多个U程 而以前一天就创徏了上千个U程 所以还是有用的

thread_concurrency

#讄Z的cpu数目x2,例如Q只有一个cpu,那么thread_concurrency=2
#?个cpu,那么thread_concurrency=4
skip-innodb
#Linnodb支持

代码:

# Example MySQL config file for medium systems.
#
# This is for a system with little memory (32M - 64M) where MySQL plays
# an important part, or systems up to 128M where MySQL is used together with
# other programs (such as a web server)
#
# You can copy this file to
# /etc/my.cnf to set global options,
# mysql-data-dir/my.cnf to set server-specific options (in this
# installation this directory is /var/lib/mysql) or
# ~/.my.cnf to set user-specific options.
#
# In this file, you can use all long options that a program supports.
# If you want to know which options a program supports, run the program
# with the "--help" option.

# The following options will be passed to all MySQL clients [client] #password = your_password port = 3306 socket = /tmp/mysql.sock #socket = /var/lib/mysql/mysql.sock # Here follows entries for some specific programs
# The MySQL server [mysqld] port = 3306 socket = /tmp/mysql.sock #socket = /var/lib/mysql/mysql.sock skip-locking key_buffer = 128M max_allowed_packet = 1M table_cache = 256 sort_buffer_size = 1M net_buffer_length = 16K myisam_sort_buffer_size = 1M max_connections=120 #addnew config wait_timeout =120 back_log=100 read_buffer_size = 1M thread_cache=32 skip-innodb skip-bdb skip-name-resolve join_buffer_size=512k query_cache_size = 32M interactive_timeout=120 long_query_time=10 log_slow_queries= /usr/local/mysql4/logs/slow_query.log query_cache_type= 1 # Try number of CPU's*2 for thread_concurrency thread_concurrency = 4
#end new config # Don't listen on a TCP/IP port at all. This can be a security enhancement, # if all processes that need to connect to mysqld run on the same host. # All interaction with mysqld must be made via Unix sockets or named pipes. # Note that using this option without enabling named pipes on Windows # (via the "enable-named-pipe" option) will render mysqld useless! # #skip-networking
# Replication Master Server (default) # binary logging is required for replication #log-bin
# required unique id between 1 and 2^32 - 1 # defaults to 1 if master-host is not set # but will not function as a master if omitted server-id = 1
# Replication Slave (comment out master section to use this) # # To configure this host as a replication slave, you can choose between # two methods : # # 1) Use the CHANGE MASTER TO command (fully described in our manual) - # the syntax is: # # CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=, # MASTER_USER=, MASTER_PASSWORD= ; # # where you replace , , by quoted strings and # by the master's port number (3306 by default). # # Example: # # CHANGE MASTER TO MASTER_HOST='125.564.12.1', MASTER_PORT=3306, # MASTER_USER='joe', MASTER_PASSWORD='secret'; # # OR # # 2) Set the variables below. However, in case you choose this method, then # start replication for the first time (even unsuccessfully, for example # if you mistyped the password in master-password and the slave fails to # connect), the slave will create a master.info file, and any later # change in this file to the variables' values below will be ignored and # overridden by the content of the master.info file, unless you shutdown # the slave server, delete master.info and restart the slaver server. # For that reason, you may want to leave the lines below untouched # (commented) and instead use CHANGE MASTER TO (see above) # # required unique id between 2 and 2^32 - 1 # (and different from the master) # defaults to 2 if master-host is set # but will not function as a slave if omitted #server-id = 2 # # The replication master for this slave - required #master-host = # # The username the slave will use for authentication when connecting # to the master - required #master-user = # # The password the slave will authenticate with when connecting to # the master - required #master-password = # # The port the master is listening on. # optional - defaults to 3306 #master-port = # # binary logging - not required for slaves, but recommended #log-bin
# Point the following paths to different dedicated disks #tmpdir = /tmp/ #log-update = /path-to-dedicated-directory/hostname
# Uncomment the following if you are using BDB tables #bdb_cache_size = 4M #bdb_max_lock = 10000
# Uncomment the following if you are using InnoDB tables #innodb_data_home_dir = /var/lib/mysql/ #innodb_data_file_path = ibdata1:10M:autoextend #innodb_log_group_home_dir = /var/lib/mysql/ #innodb_log_arch_dir = /var/lib/mysql/ # You can set .._buffer_pool_size up to 50 - 80 % # of RAM but beware of setting memory usage too high #innodb_buffer_pool_size = 16M #innodb_additional_mem_pool_size = 2M # Set .._log_file_size to 25 % of buffer pool size #innodb_log_file_size = 5M #innodb_log_buffer_size = 8M #innodb_flush_log_at_trx_commit = 1 #innodb_lock_wait_timeout = 50
[mysqldump] quick max_allowed_packet = 16M
[mysql] no-auto-rehash # Remove the next comment character if you are not familiar with SQL #safe-updates
[isamchk] key_buffer = 20M sort_buffer_size = 20M read_buffer = 2M write_buffer = 2M
[myisamchk] key_buffer = 20M sort_buffer_size = 20M read_buffer = 2M write_buffer = 2M
[mysqlhotcopy] interactive-timeout

补充

优化table_cachetable_cache指定表高速缓存的大小。每当MySQL讉K一个表Ӟ如果在表~冲Zq有I间Q该表就被打开q放入其中,q样可以更快地访问表内容。通过查峰值时间的状态值Open_tables和Opened_tablesQ可以决定是否需要增加table_cache的倹{如果你发现open_tables{于table_cacheQƈ且opened_tables在不断增长,那么你就需要增加table_cache的gQ上q状态值可以用SHOW STATUS LIKE ‘Open%tables’获得Q。注意,不能盲目地把table_cache讄成很大的倹{如果设|得太高Q可能会造成文g描述W不I从而造成性能不稳定或者连接失败。对于有1G内存的机器,推荐值是128Q?56?

案例1Q该案例来自一个不是特别繁忙的服务器table_cache – 512open_tables – 103opened_tables – 1273uptime – 4021421 (measured in seconds)该案例中table_cacheg讄得太高了。在峰值时_打开表的数目比table_cache要少得多?

案例2Q该案例来自一台开发服务器。table_cache – 64open_tables – 64opened-tables – 431uptime – 1662790 (measured in seconds)虽然open_tables已经{于table_cacheQ但是相对于服务器运行时间来_opened_tables的g非常低。因此,增加table_cache的值应该用处不大。案?Q该案例来自一个upderperforming的服务器table_cache – 64open_tables – 64opened_tables – 22423uptime – 19538该案例中table_cache讄得太低了。虽然运行时间不?时Qopen_tables辑ֈ了最大|opened_tables的g非常高。这样就需要增加table_cache的倹{优化key_buffer_sizekey_buffer_size指定索引~冲区的大小Q它军_索引处理的速度Q尤其是索引ȝ速度。通过查状态值Key_read_requests和Key_readsQ可以知道key_buffer_size讄是否合理。比例key_reads / key_read_requests应该可能的低,臛_?:100Q?:1000更好Q上q状态值可以用SHOW STATUS LIKE ‘key_read%’获得Q。key_buffer_size只对MyISAM表v作用。即使你不用MyISAM表,但是内部的时磁盘表是MyISAM表,也要使用该倹{可以用检查状态值created_tmp_disk_tables得知详情。对?G内存的机器,如果不用MyISAM表,推荐值是16MQ?-64MQ?

案例1Q健L况key_buffer_size – 402649088 (384M)key_read_requests – 597579931key_reads - 56188案例2Q警报状态key_buffer_size – 16777216 (16M)key_read_requests – 597579931key_reads - 53832731案例1中比例低?:10000Q是健康的情况;案例2中比例达?:11Q警报已l拉响?



jezz 2007-10-29 22:04 发表评论
]]>
վ֩ģ壺 | | | | | | | | Ѱ| Դ| | üɽ| | | | | «| | | | ԣ| ƽ| | | | | ̨| ʯ| | ͨ| | | Ͷ| | ƽ| ʯɽ| | ţ| | ƽ| ͨ|