<?xml version="1.0" encoding="UTF-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html"><![CDATA[Jorkin - 蜗居，我们离“家”越来越远。]]></title>
  <subtitle type="html"><![CDATA[为了谁？为了什么？值不值得？为什么别人那么幸福？-ReallyDo.Com]]></subtitle>
  <id>http://Jorkin.Reallydo.Com/</id> 
  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/" /> 
  <link rel="self" type="application/atom+xml" href="http://Jorkin.Reallydo.Com/atom.asp" /> 
  <generator uri="http://www.pjhome.net/" version="2.4.1022">PJBlog2</generator> 
  <updated>2010-02-15T12:59:09+08:00</updated> 

  <entry>
	  <title type="html"><![CDATA[Max and the Magic Marker RIP-Unleashed]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=8" label="其它转载" /> 
	  <updated>2010-02-15T12:59:09+08:00</updated>
	  <published>2010-02-15T12:59:09+08:00</published>
		  <summary type="html"><![CDATA[<p>Description: Max the Magic Marker is a physics based 2D puzzle platformer, in which the player controls the boy Max and his Magic Marker. While Max enables good old platforming fun, the marker provides the game?s signature feature: the ability for the player to draw directly inside the game world where everything drawn becomes physical objects. This feature is used to complete levels and overcome challenges but it also provides the player with a unique tool that in itself is fun to play around with.</p>
<p>Features:</p>
<p>15 inventive and puzzling levels<br />Unique drawing control in a truly dynamic physics environment 3 beautiful worlds inspired by childrens drawings<br />Death traps, monsters, and challenging puzzles Unlockable challenges, secrets and rewards<br />Original and awesome soundtrack by Analogik</p>
<p>Release Name: Max.and.the.Magic.Marker.RIP-Unleashed<br />Size: 72.6 MB</p>
<p>Download:<br />&nbsp;<br /><a href="http://hotfile.com/dl/27346440/9595a86/MaMMarker-Unleashed.zip.html">http://hotfile.com/dl/27346440/9595a86/MaMMarker-Unleashed.zip.html</a><br />or<br /><a href="http://ugotfile.com/file/817972/MaMMarker-Unleashed.zip">http://ugotfile.com/file/817972/MaMMarker-Unleashed.zip</a><br />or<br /><a href="http://rapidshare.com/files/346517951/MaMMarker-Unleashed.zip">http://rapidshare.com/files/346517951/MaMMarker-Unleashed.zip</a></p>]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=658" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=658</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Managing Hierarchical Data in MySQL]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=1" label="技术天地" /> 
	  <updated>2010-02-01T16:16:56+08:00</updated>
	  <published>2010-02-01T16:16:56+08:00</published>
		  <summary type="html"><![CDATA[<p>中文翻译：<a href="http://www.cnblogs.com/phaibin/archive/2009/06/09/1499687.html" target="_blank">http://www.cnblogs.com/phaibin/archive/2009/06/09/1499687.html</a></p>
<p>下载：<a href="http://www.itpub.net/viewthread.php?tid=1260440" target="_blank">Joe Celko's.Trees and Hierarchies in SQL for Smarties.pdf</a></p>
<p>其它资源：<a href="http://www.itpub.net/thread-1233846-1-1.html" target="_blank">http://www.itpub.net/thread-1233846-1-1.html</a></p>
<h3>Introduction</h3>
<p>Most users at one time or another have dealt with hierarchical data in a SQL database and no doubt learned that the management of hierarchical data is not what a relational database is intended for. The tables of a relational database are not hierarchical (like XML), but are simply a flat list. Hierarchical data has a parent-child relationship that is not naturally represented in a relational database table.</p>
<p>For our purposes, hierarchical data is a collection of data where each item has a single parent and zero or more children (with the exception of the root item, which has no parent). Hierarchical data can be found in a variety of database applications, including forum and mailing list threads, business organization charts, content management categories, and product categories. For our purposes we will use the following product category hierarchy from an fictional electronics store:</p>
<p><img alt="" src="http://jorkin.reallydo.com/UPLOAD/month_1001/hierarchical-data-1.png" /></p>
<p>These categories form a hierarchy in much the same way as the other examples cited above. In this article we will examine two models for dealing with hierarchical data in MySQL, starting with the traditional adjacency list model.</p>
<h3>The Adjacency List Model</h3>
<p>Typically the example categories shown above will be stored in a table like the following (I'm including full Create and Insert statements so you can follow along):</p>
<pre>Create TABLE category(
category_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
parent INT DEFAULT NULL);
Insert INTO category
VALUES(1,'ELECTRONICS',NULL),(2,'TELEVISIONS',1),(3,'TUBE',2),
(4,'LCD',2),(5,'PLASMA',2),(6,'PORTABLE ELECTRONICS',1),
(7,'MP3 PLAYERS',6),(8,'FLASH',7),
(9,'CD PLAYERS',6),(10,'2 WAY RADIOS',6);
Select * FROM category orDER BY category_id;
+-------------+----------------------+--------+
| category_id | name                 | parent |
+-------------+----------------------+--------+
|           1 | ELECTRONICS          |   NULL |
|           2 | TELEVISIONS          |      1 |
|           3 | TUBE                 |      2 |
|           4 | LCD                  |      2 |
|           5 | PLASMA               |      2 |
|           6 | PORTABLE ELECTRONICS |      1 |
|           7 | MP3 PLAYERS          |      6 |
|           8 | FLASH                |      7 |
|           9 | CD PLAYERS           |      6 |
|          10 | 2 WAY RADIOS         |      6 |
+-------------+----------------------+--------+
10 rows in set (0.00 sec)
</pre>
<p>In the adjacency list model, each item in the table contains a pointer to its parent. The topmost element, in this case electronics, has a NULL value for its parent. The adjacency list model has the advantage of being quite simple, it is easy to see that FLASH is a child of mp3 players, which is a child of portable electronics, which is a child of electronics. While the adjacency list model can be dealt with fairly easily in client-side code, working with the model can be more problematic in pure SQL.</p>
<h3>Retrieving a Full Tree</h3>
<p>The first common task when dealing with hierarchical data is the display of the entire tree, usually with some form of indentation. The most common way of doing this is in pure SQL is through the use of a self-join:</p>
<pre>Select t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
Where t1.name = 'ELECTRONICS';
+-------------+----------------------+--------------+-------+
| lev1        | lev2                 | lev3         | lev4  |
+-------------+----------------------+--------------+-------+
| ELECTRONICS | TELEVISIONS          | TUBE         | NULL  |
| ELECTRONICS | TELEVISIONS          | LCD          | NULL  |
| ELECTRONICS | TELEVISIONS          | PLASMA       | NULL  |
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS  | FLASH |
| ELECTRONICS | PORTABLE ELECTRONICS | CD PLAYERS   | NULL  |
| ELECTRONICS | PORTABLE ELECTRONICS | 2 WAY RADIOS | NULL  |
+-------------+----------------------+--------------+-------+
6 rows in set (0.00 sec)
</pre>
<h3>Finding all the Leaf Nodes</h3>
<p>We can find all the leaf nodes in our tree (those with no children) by using a LEFT JOIN query:</p>
<pre>Select t1.name FROM
category AS t1 LEFT JOIN category as t2
ON t1.category_id = t2.parent
Where t2.category_id IS NULL;
+--------------+
| name         |
+--------------+
| TUBE         |
| LCD          |
| PLASMA       |
| FLASH        |
| CD PLAYERS   |
| 2 WAY RADIOS |
+--------------+
</pre>
<h3>Retrieving a Single Path</h3>
<p>The self-join also allows us to see the full path through our hierarchies:</p>
<pre>Select t1.name AS lev1, t2.name as lev2, t3.name as lev3, t4.name as lev4
FROM category AS t1
LEFT JOIN category AS t2 ON t2.parent = t1.category_id
LEFT JOIN category AS t3 ON t3.parent = t2.category_id
LEFT JOIN category AS t4 ON t4.parent = t3.category_id
Where t1.name = 'ELECTRONICS' AND t4.name = 'FLASH';
+-------------+----------------------+-------------+-------+
| lev1        | lev2                 | lev3        | lev4  |
+-------------+----------------------+-------------+-------+
| ELECTRONICS | PORTABLE ELECTRONICS | MP3 PLAYERS | FLASH |
+-------------+----------------------+-------------+-------+
1 row in set (0.01 sec)
</pre>
<p>The main limitation of such an approach is that you need one self-join for every level in the hierarchy, and performance will naturally degrade with each level added as the joining grows in complexity.</p>
<h3>Limitations of the Adjacency List Model</h3>
<p>Working with the adjacency list model in pure SQL can be difficult at best. Before being able to see the full path of a category we have to know the level at which it resides. In addition, special care must be taken when deleting nodes because of the potential for orphaning an entire sub-tree in the process (delete the portable electronics category and all of its children are orphaned). Some of these limitations can be addressed through the use of client-side code or stored procedures. With a procedural language we can start at the bottom of the tree and iterate upwards to return the full tree or a single path. We can also use procedural programming to delete nodes without orphaning entire sub-trees by promoting one child element and re-ordering the remaining children to point to the new parent.</p>
<h3>The Nested Set Model</h3>
<p>What I would like to focus on in this article is a different approach, commonly referred to as the <b>Nested Set Model</b>. In the Nested Set Model, we can look at our hierarchy in a new way, not as nodes and lines, but as nested containers. Try picturing our electronics categories this way:</p>
<p><img alt="" src="http://jorkin.reallydo.com/UPLOAD/month_1001/hierarchical-data-2.png" /></p>
<p>Notice how our hierarchy is still maintained, as parent categories envelop their children.We represent this form of hierarchy in a table through the use of left and right values to represent the nesting of our nodes:</p>
<pre>Create TABLE nested_category (
category_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
lft INT NOT NULL,
rgt INT NOT NULL
);
Insert INTO nested_category
VALUES(1,'ELECTRONICS',1,20),(2,'TELEVISIONS',2,9),(3,'TUBE',3,4),
(4,'LCD',5,6),(5,'PLASMA',7,8),(6,'PORTABLE ELECTRONICS',10,19),
(7,'MP3 PLAYERS',11,14),(8,'FLASH',12,13),
(9,'CD PLAYERS',15,16),(10,'2 WAY RADIOS',17,18);
Select * FROM nested_category orDER BY category_id;
+-------------+----------------------+-----+-----+
| category_id | name                 | lft | rgt |
+-------------+----------------------+-----+-----+
|           1 | ELECTRONICS          |   1 |  20 |
|           2 | TELEVISIONS          |   2 |   9 |
|           3 | TUBE                 |   3 |   4 |
|           4 | LCD                  |   5 |   6 |
|           5 | PLASMA               |   7 |   8 |
|           6 | PORTABLE ELECTRONICS |  10 |  19 |
|           7 | MP3 PLAYERS          |  11 |  14 |
|           8 | FLASH                |  12 |  13 |
|           9 | CD PLAYERS           |  15 |  16 |
|          10 | 2 WAY RADIOS         |  17 |  18 |
+-------------+----------------------+-----+-----+
</pre>
<p>We use <b>lft</b> and <b>rgt</b> because left and right are reserved words in MySQL, see <a href="http://dev.mysql.com/doc/mysql/en/reserved-words.html" target="_blank">http://dev.mysql.com/doc/mysql/en/reserved-words.html</a> for the full list of reserved words.</p>
<p>So how do we determine left and right values? We start numbering at the leftmost side of the outer node and continue to the right:</p>
<p><img alt="" src="http://jorkin.reallydo.com/UPLOAD/month_1001/hierarchical-data-3.png" /></p>
<p>This design can be applied to a typical tree as well:</p>
<p><img alt="" src="http://jorkin.reallydo.com/UPLOAD/month_1001/hierarchical-data-4.png" /></p>
<p>When working with a tree, we work from left to right, one layer at a time, descending to each node's children before assigning a right-hand number and moving on to the right. This approach is called the modified <b>preorder tree traversal algorithm.</b></p>
<h3>Retrieving a Full Tree</h3>
<p>We can retrieve the full tree through the use of a self-join that links parents with nodes on the basis that a node's <b>lft</b> value will always appear between its parent's <b>lft</b> and <b>rgt</b> values:</p>
<pre>Select node.name
FROM nested_category AS node,
nested_category AS parent
Where node.lft BETWEEN parent.lft AND parent.rgt
AND parent.name = 'ELECTRONICS'
orDER BY node.lft;
+----------------------+
| name                 |
+----------------------+
| ELECTRONICS          |
| TELEVISIONS          |
| TUBE                 |
| LCD                  |
| PLASMA               |
| PORTABLE ELECTRONICS |
| MP3 PLAYERS          |
| FLASH                |
| CD PLAYERS           |
| 2 WAY RADIOS         |
+----------------------+
</pre>
<p>Unlike our previous examples with the adjacency list model, this query will work regardless of the depth of the tree. We do not concern ourselves with the rgt value of the node in our BETWEEN clause because the rgt value will always fall within the same parent as the lft values.</p>
<h3>Finding all the Leaf Nodes</h3>
<p>Finding all leaf nodes in the nested set model even simpler than the LEFT JOIN method used in the adjacency list model. If you look at the nested_category table, you may notice that the lft and rgt values for leaf nodes are consecutive numbers. To find the leaf nodes, we look for nodes where rgt = lft + 1:</p>
<pre>Select name
FROM nested_category
Where rgt = lft + 1;
+--------------+
| name         |
+--------------+
| TUBE         |
| LCD          |
| PLASMA       |
| FLASH        |
| CD PLAYERS   |
| 2 WAY RADIOS |
+--------------+
</pre>
<h3>Retrieving a Single Path</h3>
<p>With the nested set model, we can retrieve a single path without having multiple self-joins:</p>
<pre>Select parent.name
FROM nested_category AS node,
nested_category AS parent
Where node.lft BETWEEN parent.lft AND parent.rgt
AND node.name = 'FLASH'
orDER BY parent.lft;
+----------------------+
| name                 |
+----------------------+
| ELECTRONICS          |
| PORTABLE ELECTRONICS |
| MP3 PLAYERS          |
| FLASH                |
+----------------------+
</pre>
<h3>Finding the Depth of the Nodes</h3>
<p>We have already looked at how to show the entire tree, but what if we want to also show the depth of each node in the tree, to better identify how each node fits in the hierarchy? This can be done by adding a COUNT function and a GROUP BY clause to our existing query for showing the entire tree:</p>
<pre>Select node.name, (COUNT(parent.name) - 1) AS depth
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;
+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| ELECTRONICS          |     0 |
| TELEVISIONS          |     1 |
| TUBE                 |     2 |
| LCD                  |     2 |
| PLASMA               |     2 |
| PORTABLE ELECTRONICS |     1 |
| MP3 PLAYERS          |     2 |
| FLASH                |     3 |
| CD PLAYERS           |     2 |
| 2 WAY RADIOS         |     2 |
+----------------------+-------+
</pre>
<p>We can use the depth value to indent our category names with the CONCAT and REPEAT string functions:</p>
<pre>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;
+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
+-----------------------+
</pre>
<p>Of course, in a client-side application you will be more likely to use the depth value directly to display your hierarchy. Web developers could loop through the tree, adding &lt;li&gt;&lt;/li&gt; and &lt;ul&gt;&lt;/ul&gt; tags as the depth number increases and decreases.</p>
<h3>Depth of a Sub-Tree</h3>
<p>When we need depth information for a sub-tree, we cannot limit either the node or parent tables in our self-join because it will corrupt our results. Instead, we add a third self-join, along with a sub-query to determine the depth that will be the new starting point for our sub-tree:</p>
<pre>Select node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
nested_category AS parent,
nested_category AS sub_parent,
(
Select node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node,
nested_category AS parent
Where node.lft BETWEEN parent.lft AND parent.rgt
AND node.name = 'PORTABLE ELECTRONICS'
GROUP BY node.name
orDER BY node.lft
)AS sub_tree
Where node.lft BETWEEN parent.lft AND parent.rgt
AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
AND sub_parent.name = sub_tree.name
GROUP BY node.name
orDER BY node.lft;
+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| PORTABLE ELECTRONICS |     0 |
| MP3 PLAYERS          |     1 |
| FLASH                |     2 |
| CD PLAYERS           |     1 |
| 2 WAY RADIOS         |     1 |
+----------------------+-------+
</pre>
<p>This function can be used with any node name, including the root node. The depth values are always relative to the named node.</p>
<h3>Find the Immediate Subordinates of a Node</h3>
<p>Imagine you are showing a category of electronics products on a retailer web site. When a user clicks on a category, you would want to show the products of that category, as well as list its immediate sub-categories, but not the entire tree of categories beneath it. For this, we need to show the node and its immediate sub-nodes, but no further down the tree. For example, when showing the PORTABLE ELECTRONICS category, we will want to show MP3 PLAYERS, CD PLAYERS, and 2 WAY RADIOS, but not FLASH.</p>
<p>This can be easily accomplished by adding a HAVING clause to our previous query:</p>
<pre>Select node.name, (COUNT(parent.name) - (sub_tree.depth + 1)) AS depth
FROM nested_category AS node,
nested_category AS parent,
nested_category AS sub_parent,
(
Select node.name, (COUNT(parent.name) - 1) AS depth
FROM nested_category AS node,
nested_category AS parent
Where node.lft BETWEEN parent.lft AND parent.rgt
AND node.name = 'PORTABLE ELECTRONICS'
GROUP BY node.name
orDER BY node.lft
)AS sub_tree
Where node.lft BETWEEN parent.lft AND parent.rgt
AND node.lft BETWEEN sub_parent.lft AND sub_parent.rgt
AND sub_parent.name = sub_tree.name
GROUP BY node.name
HAVING depth &lt;= 1
orDER BY node.lft;
+----------------------+-------+
| name                 | depth |
+----------------------+-------+
| PORTABLE ELECTRONICS |     0 |
| MP3 PLAYERS          |     1 |
| CD PLAYERS           |     1 |
| 2 WAY RADIOS         |     1 |
+----------------------+-------+
</pre>
<p>If you do not wish to show the parent node, change the <b>HAVING depth &lt;= 1 line to HAVING depth = 1</b>.</p>
<h3>Aggregate Functions in a Nested Set</h3>
<p>Let's add a table of products that we can use to demonstrate aggregate functions with:</p>
<pre>Create TABLE product(
product_id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(40),
category_id INT NOT NULL
);
Insert INTO product(name, category_id) VALUES('20&quot; TV',3),('36&quot; TV',3),
('Super-LCD 42&quot;',4),('Ultra-Plasma 62&quot;',5),('Value Plasma 38&quot;',5),
('Power-MP3 5gb',7),('Super-Player 1gb',8),('Porta CD',9),('CD To go!',9),
('Family Talk 360',10);
Select * FROM product;
+------------+-------------------+-------------+
| product_id | name              | category_id |
+------------+-------------------+-------------+
|          1 | 20&quot; TV            |           3 |
|          2 | 36&quot; TV            |           3 |
|          3 | Super-LCD 42&quot;     |           4 |
|          4 | Ultra-Plasma 62&quot;  |           5 |
|          5 | Value Plasma 38&quot;  |           5 |
|          6 | Power-MP3 128mb   |           7 |
|          7 | Super-Shuffle 1gb |           8 |
|          8 | Porta CD          |           9 |
|          9 | CD To go!         |           9 |
|         10 | Family Talk 360   |          10 |
+------------+-------------------+-------------+
</pre>
<p>Now let's produce a query that can retrieve our category tree, along with a product count for each category:</p>
<pre>Select parent.name, COUNT(product.name)
FROM nested_category AS node ,
nested_category AS parent,
product
Where node.lft BETWEEN parent.lft AND parent.rgt
AND node.category_id = product.category_id
GROUP BY parent.name
orDER BY node.lft;
+----------------------+---------------------+
| name                 | COUNT(product.name) |
+----------------------+---------------------+
| ELECTRONICS          |                  10 |
| TELEVISIONS          |                   5 |
| TUBE                 |                   2 |
| LCD                  |                   1 |
| PLASMA               |                   2 |
| PORTABLE ELECTRONICS |                   5 |
| MP3 PLAYERS          |                   2 |
| FLASH                |                   1 |
| CD PLAYERS           |                   2 |
| 2 WAY RADIOS         |                   1 |
+----------------------+---------------------+
</pre>
<p>This is our typical whole tree query with a COUNT and GROUP BY added, along with a reference to the product table and a join between the node and product table in the Where clause. As you can see, there is a count for each category and the count of subcategories is reflected in the parent categories.</p>
<h3>Adding New Nodes</h3>
<p>Now that we have learned how to query our tree, we should take a look at how to update our tree by adding a new node. Let's look at our nested set diagram again:</p>
<p><img alt="" src="http://jorkin.reallydo.com/UPLOAD/month_1001/hierarchical-data-5.png" /></p>
<p>If we wanted to add a new node between the TELEVISIONS and PORTABLE ELECTRONICS nodes, the new node would have lft and rgt values of 10 and 11, and all nodes to its right would have their lft and rgt values increased by two. We would then add the new node with the appropriate lft and rgt values. While this can be done with a stored procedure in MySQL 5, I will assume for the moment that most readers are using 4.1, as it is the latest stable version, and I will isolate my queries with a LOCK TABLES statement instead:</p>
<pre>LOCK TABLE nested_category WRITE;
Select @myRight := rgt FROM nested_category
Where name = 'TELEVISIONS';
Update nested_category SET rgt = rgt + 2 Where rgt &gt; @myRight;
Update nested_category SET lft = lft + 2 Where lft &gt; @myRight;
Insert INTO nested_category(name, lft, rgt) VALUES('GAME CONSOLES', @myRight + 1, @myRight + 2);
UNLOCK TABLES;
We can then check our nesting with our indented tree query:
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;
+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  GAME CONSOLES        |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
+-----------------------+
</pre>
<p>If we instead want to add a node as a child of a node that has no existing children, we need to modify our procedure slightly. Let's add a new FRS node below the 2 WAY RADIOS node:</p>
<pre>LOCK TABLE nested_category WRITE;
Select @myLeft := lft FROM nested_category
Where name = '2 WAY RADIOS';
Update nested_category SET rgt = rgt + 2 Where rgt &gt; @myLeft;
Update nested_category SET lft = lft + 2 Where lft &gt; @myLeft;
Insert INTO nested_category(name, lft, rgt) VALUES('FRS', @myLeft + 1, @myLeft + 2);
UNLOCK TABLES;
</pre>
<p>In this example we expand everything to the right of the left-hand number of our proud new parent node, then place the node to the right of the left-hand value. As you can see, our new node is now properly nested:</p>
<pre>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;
+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  GAME CONSOLES        |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
|    FRS                |
+-----------------------+
</pre>
<h3>Deleting Nodes</h3>
<p>The last basic task involved in working with nested sets is the removal of nodes. The course of action you take when deleting a node depends on the node's position in the hierarchy; deleting leaf nodes is easier than deleting nodes with children because we have to handle the orphaned nodes.</p>
<p>When deleting a leaf node, the process if just the opposite of adding a new node, we delete the node and its width from every node to its right:</p>
<pre>LOCK TABLE nested_category WRITE;
Select @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
Where name = 'GAME CONSOLES';
Delete FROM nested_category Where lft BETWEEN @myLeft AND @myRight;
Update nested_category SET rgt = rgt - @myWidth Where rgt &gt; @myRight;
Update nested_category SET lft = lft - @myWidth Where lft &gt; @myRight;
UNLOCK TABLES;
</pre>
<p>And once again, we execute our indented tree query to confirm that our node has been deleted without corrupting the hierarchy:</p>
<pre>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;
+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  PORTABLE ELECTRONICS |
|   MP3 PLAYERS         |
|    FLASH              |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
|    FRS                |
+-----------------------+
</pre>
<p>This approach works equally well to delete a node and all its children:</p>
<pre>LOCK TABLE nested_category WRITE;
Select @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
Where name = 'MP3 PLAYERS';
Delete FROM nested_category Where lft BETWEEN @myLeft AND @myRight;
Update nested_category SET rgt = rgt - @myWidth Where rgt &gt; @myRight;
Update nested_category SET lft = lft - @myWidth Where lft &gt; @myRight;
UNLOCK TABLES;
</pre>
<p>And once again, we query to see that we have successfully deleted an entire sub-tree:</p>
<pre>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;
+-----------------------+
| name                  |
+-----------------------+
| ELECTRONICS           |
|  TELEVISIONS          |
|   TUBE                |
|   LCD                 |
|   PLASMA              |
|  PORTABLE ELECTRONICS |
|   CD PLAYERS          |
|   2 WAY RADIOS        |
|    FRS                |
+-----------------------+
</pre>
<p>The other scenario we have to deal with is the deletion of a parent node but not the children. In some cases you may wish to just change the name to a placeholder until a replacement is presented, such as when a supervisor is fired. In other cases, the child nodes should all be moved up to the level of the deleted parent:</p>
<pre>LOCK TABLE nested_category WRITE;
Select @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1
FROM nested_category
Where name = 'PORTABLE ELECTRONICS';
Delete FROM nested_category Where lft = @myLeft;
Update nested_category SET rgt = rgt - 1, lft = lft - 1 Where lft BETWEEN @myLeft AND @myRight;
Update nested_category SET rgt = rgt - 2 Where rgt &gt; @myRight;
Update nested_category SET lft = lft - 2 Where lft &gt; @myRight;
UNLOCK TABLES;
</pre>
<p>In this case we subtract two from all elements to the right of the node (since without children it would have a width of two), and one from the nodes that are its children (to close the gap created by the loss of the parent's left value). Once again, we can confirm our elements have been promoted:</p>
<pre>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;
+---------------+
| name          |
+---------------+
| ELECTRONICS   |
|  TELEVISIONS  |
|   TUBE        |
|   LCD         |
|   PLASMA      |
|  CD PLAYERS   |
|  2 WAY RADIOS |
|   FRS         |
+---------------+
</pre>
<p>Other scenarios when deleting nodes would include promoting one of the children to the parent position and moving the child nodes under a sibling of the parent node, but for the sake of space these scenarios will not be covered in this article.</p>
<h3>Final Thoughts</h3>
<p>While I hope the information within this article will be of use to you, the concept of nested sets in SQL has been around for over a decade, and there is a lot of additional information available in books and on the Internet. In my opinion the most comprehensive source of information on managing hierarchical information is a book called <a href="http://www.openwin.org/mike/books/index.php/trees-and-hierarchies-in-sql" target="_blank">Joe Celko's Trees and Hierarchies in SQL for Smarties</a>, written by a very respected author in the field of advanced SQL, Joe Celko. Joe Celko is often credited with the nested sets model and is by far the most prolific author on the subject. I have found Celko's book to be an invaluable resource in my own studies and highly recommend it. The book covers advanced topics which I have not covered in this article, and provides additional methods for managing hierarchical data in addition to the Adjacency List and Nested Set models.</p>
<p>In the References / Resources section that follows I have listed some web resources that may be of use in your research of managing hierarchal data, including a pair of PHP related resources that include pre-built PHP libraries for handling nested sets in MySQL. Those of you who currently use the adjacency list model and would like to experiment with the nested set model will find sample code for converting between the two in the <a href="http://www.sitepoint.com/article/hierarchical-data-database" target="_blank">Storing Hierarchical Data in a Database</a> resource listed below.</p>]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=657" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=657</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[Kin_Db_Pager2进行中]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=9" label="胡诌乱侃" /> 
	  <updated>2010-01-19T14:25:30+08:00</updated>
	  <published>2010-01-19T14:25:30+08:00</published>
		  <summary type="html"><![CDATA[<p>Feature:</p>
<ol>
    <li>为优化MSSQL加了N多垃圾代码，提高百万数据量时的速度。 </li>
    <li>添加CreateIndex()方法，可以在DEBUG模式下帮助数据库新手创建简单索引。 </li>
    <li>添加GetRows()方法。 </li>
    <li>临时删除Oracle相关代码。 </li>
    <li>生成分页列表时不再采用字符串串联，改用数组。 </li>
    <li>其他小修改。 </li>
</ol>]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=656" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=656</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[因为转载 一位小学生的《夜宴》观后感 Blog被关N天]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=9" label="胡诌乱侃" /> 
	  <updated>2009-12-28T12:44:24+08:00</updated>
	  <published>2009-12-28T12:44:24+08:00</published>
		  <summary type="html"><![CDATA[和谐的天朝，和谐的主机供应商。]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=655" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=655</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[[原创]利用正弦函数Sin()真正实现ACCESS的随机选取记录]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=1" label="技术天地" /> 
	  <updated>2009-12-11T16:35:33+08:00</updated>
	  <published>2009-12-11T16:35:33+08:00</published>
		  <summary type="html"><![CDATA[<p>不多说了.非常简单.</p>
<p>建一个ASP函数:<br /><a href="http://jorkin.reallydo.com/article.asp?id=653" target="_blank">http://jorkin.reallydo.com/article.asp?id=653</a></p>
<p>ASP代码:<br />&lt;%<br />sNewOrder = NewID(&quot;id&quot;) '这里的ID是数据类型为数字(最好用自动编号列)<br />Set ors = Exec(&quot;Select Top 20 id,compname,fund,foundyear,&quot; &amp; sNewOrder &amp; &quot; AS NewID From company <font color="#ff0000">where fund&gt;100</font> order By &quot; &amp; sNewOrder)<br />Trace(oRs)<br />%&gt;<br /><br />说明：这个方法如果在记录集过大的时候也会很费时间，所以请先通过Where条件筛选后再随机排序。</p>
<p><a href="http://bbs.blueidea.com/thread-2961671-1-1.html" target="_blank">实例下载</a></p>]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=654" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=654</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[ASP常用函数:NewID()]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=19" label="敝帚自珍" /> 
	  <updated>2009-12-11T16:02:43+08:00</updated>
	  <published>2009-12-11T16:02:43+08:00</published>
		  <summary type="html"><![CDATA[<font color="#8000ff">&lt;%<br /></font><font color="#008000">'功能:真正实现ACCESS随机选取记录功能<br />'来源:http://jorkin.reallydo.com/article.asp?id=653<br /><br /></font><font color="#0000ff">Function </font>NewID<font color="#000080">(</font>PKey<font color="#000080">)<br />&nbsp;&nbsp;&nbsp;&nbsp;</font><font color="#008000">'NewID = &quot; Sin(&quot; &amp; Timer &amp; &quot;*&quot; &amp; PKey &amp; &quot;) &quot;<br />&nbsp;&nbsp;&nbsp;&nbsp;</font>NewID <font color="#000080">= </font><font color="#800000">&quot; Rnd(-&quot; </font><font color="#000080">&amp; </font>Timer <font color="#000080">&amp; </font><font color="#800000">&quot;*&quot; </font><font color="#000080">&amp; </font>PKey <font color="#000080">&amp; </font><font color="#800000">&quot;) &quot;<br /></font><font color="#0000ff">End Function<br /></font><font color="#8000ff">%&gt;<br /><br /></font>]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=653" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=653</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[[转]N个jQuery Datagrid插件 以及其他 Datagrid 脚本]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=1" label="技术天地" /> 
	  <updated>2009-11-17T15:40:58+08:00</updated>
	  <published>2009-11-17T15:40:58+08:00</published>
		  <summary type="html"><![CDATA[<p>Review of 10 jQuery datagrid plugins... </p>
<p>jqGrid</p>
<p align="center"><a href="http://jorkin.reallydo.com/upload/month_0911/jqgrid.png" rel="lightbox" target="_blank"><img title="jqGrid plugin" border="0" alt="jqGrid plugin" src="http://jorkin.reallydo.com/upload/month_0911/jqgrid.png" width="644" height="232" /></a><br /><a href="http://www.trirand.com/blog/" target="_blank">HOME</a> | <a href="http://www.trirand.com/jqgrid35/jqgrid.html" target="_blank">DEMO</a> | Last Update: May 2009</p>
<ul>
    <li>paging functions </li>
    <li>sortable column headers </li>
    <li>add, edit, delete &amp; search records </li>
    <li>accepts XML, JSON, array or user data as input </li>
    <li>multiple selection of rows </li>
    <li>sub grid &amp; grid details </li>
    <li>support UI themes </li>
    <li>UI Datepicker integration </li>
    <li>API </li>
    <li>big size </li>
</ul>
<p>Flexigrid</p>
<p align="center"><a href="http://jorkin.reallydo.com/upload/month_0911/flexigrid.png" rel="lightbox" target="_blank"><img title="Flexigrid plugin" border="0" alt="Flexigrid plugin" src="http://jorkin.reallydo.com/upload/month_0911/flexigrid.png" width="700" height="316" /></a><br /><a href="http://www.flexigrid.info/" target="_blank">HOME</a> | Last Update: July 2008</p>
<ul>
    <li>paging functions </li>
    <li>sortable column headers </li>
    <li>add, edit, delete &amp; search records </li>
    <li>accepts XML, JSON, array or user data as input </li>
    <li>nice design </li>
    <li>API </li>
    <li>don't support last jQuery version </li>
</ul>
<p>Ingrid</p>
<p align="center"><a href="http://jorkin.reallydo.com/upload/month_0911/ingrid.png" rel="lightbox" target="_blank"><img title="Ingrid plugin" border="0" alt="Ingrid plugin" src="http://jorkin.reallydo.com/upload/month_0911/ingrid.png" width="600" height="266" /></a><br /><a href="http://reconstrukt.com/ingrid/" target="_blank">HOME</a> | Last Update: November 2007</p>
<ul>
    <li>paging functions </li>
    <li>sortable column headers </li>
    <li>nice design </li>
    <li>project is die </li>
</ul>
<p>jTPS</p>
<p align="center"><a href="http://jorkin.reallydo.com/upload/month_0911/jtps.png" rel="lightbox" target="_blank"><img title="jTPS plugin" border="0" alt="jTPS plugin" src="http://jorkin.reallydo.com/upload/month_0911/jtps.png" width="703" height="399" /></a><br /><a href="http://www.overset.com/2008/08/30/animated-sortable-datagrid-jquery-plugin-jtps/" target="_blank">HOME</a> | <a href="http://overset.com/upload/jTPS/jTPS.html" target="_blank">DEMO</a> | Last Update: August 2008</p>
<ul>
    <li>paging functions </li>
    <li>sortable column headers </li>
    <li>animate sorting and page navigation </li>
    <li>don't support AJAX </li>
</ul>
<p>FireScope Grid</p>
<p align="center"><a href="http://jorkin.reallydo.com/upload/month_0911/firescope_grid-720x283.png" rel="lightbox" target="_blank"><img title="FireScope Grid" border="0" alt="FireScope Grid" src="http://jorkin.reallydo.com/upload/month_0911/firescope_grid-720x283.png" width="720" height="283" /></a><br /><a href="http://www.firescope.com/OpenSource/Grid/" target="_blank">HOME</a> | Last Update: February 2009</p>
<ul>
    <li>paging functions </li>
    <li>sortable column headers </li>
    <li>search records </li>
    <li>support only HTML data source </li>
</ul>
<p>tgrid</p>
<p align="center"><a href="http://jorkin.reallydo.com/upload/month_0911/tgrid.png" rel="lightbox" target="_blank"><img title="tgrid" border="0" alt="tgrid" src="http://jorkin.reallydo.com/upload/month_0911/tgrid.png" width="476" height="460" /></a><br /><a href="http://dreakmore.info/tgrid/" target="_blank">HOME</a> | <a href="http://dreakmore.info/tgrid/demos/" target="_blank">DEMO</a> | Last Update: May 2009</p>
<ul>
    <li>paging functions </li>
    <li>sortable column headers </li>
    <li>update &amp; search records </li>
    <li>young </li>
    <li>young </li>
    <li>young </li>
</ul>
<p>Datacontrol</p>
<p align="center"><a href="http://jorkin.reallydo.com/upload/month_0911/datacontrol.png" rel="lightbox" target="_blank"><img title="Datacontrol" border="0" alt="Datacontrol" src="http://jorkin.reallydo.com/upload/month_0911/datacontrol.png" width="606" height="199" /></a><br /><a href="http://www.antolcms.com/datacontrol/" target="_blank">HOME</a> | Last Update: February 2009</p>
<ul>
    <li>paging functions </li>
    <li>sortable column headers </li>
    <li>add, edit, delete &amp; search records </li>
    <li>support only XML data source (but with XLS) </li>
    <li>don't allow source </li>
</ul>
<p>DataTables</p>
<p align="center"><a href="http://jorkin.reallydo.com/upload/month_0911/datatables.png" rel="lightbox" target="_blank"><img title="DataTables" border="0" alt="DataTables" src="http://jorkin.reallydo.com/upload/month_0911/datatables.png" width="700" height="302" /></a><br /><a href="http://www.datatables.net/" target="_blank">HOME</a> | <a href="http://www.datatables.net/examples/example_zero_config.html" target="_blank">DEMO</a> | Last Update: February 2009</p>
<ul>
    <li>paging functions </li>
    <li>sortable column headers </li>
    <li>add, edit, delete &amp; search records </li>
    <li>accepts only JSON as input </li>
    <li>API </li>
    <li>fast data search </li>
</ul>
<p>Snowcore Datagrid</p>
<p align="center"><a href="http://jorkin.reallydo.com/upload/month_0911/snowscore.png" rel="lightbox" target="_blank"><img title="snowcore" border="0" alt="snowcore" src="http://jorkin.reallydo.com/upload/month_0911/snowscore.png" width="354" height="120" /></a><br /><a href="http://snowcore.net/jquery-data-grid-пишем-плагин" target="_blank">HOME</a> | <a href="http://snowcore.net/grid/" target="_blank">DEMO</a> | Last Update: December 2008</p>
<ul>
    <li>add, edit &amp; delete records </li>
    <li>young </li>
</ul>
<p>JGridEditor</p>
<p>Plugin aviable only on <a href="http://plugins.jquery.com/project/jgrideditor" target="_blank">jQuery homepage</a>.</p>
<p>Sigma Grid</p>
<p><a href="http://www.sigmawidgets.com/" target="_blank">HomePage</a> | <a href="http://www.sigmawidgets.com/products/sigma_grid/demos/index.html" target="_blank">Demo</a> | <a href="http://www.sigmawidgets.com/download.html" target="_blank">Download</a></p>]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=652" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=652</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[累]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=9" label="胡诌乱侃" /> 
	  <updated>2009-10-23T08:59:08+08:00</updated>
	  <published>2009-10-23T08:59:08+08:00</published>
		  <summary type="html"><![CDATA[<p>勞民傷財的十一。</p>]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=651" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=651</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[JavaScript Framework Matrix]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=1" label="技术天地" /> 
	  <updated>2009-09-23T23:06:34+08:00</updated>
	  <published>2009-09-23T23:06:34+08:00</published>
		  <summary type="html"><![CDATA[<p>JavaScript Framework Matrix是一个比较当前各种流行JavaScript框架功能的矩阵。所举的例子几乎涵盖了所有的功能，并提供链接指向原始文档。</p>
<p><a href="http://matthiasschuetz.com/javascript-framework-matrix/en/">http://matthiasschuetz.com/javascript-framework-matrix/en/</a></p>
<p><a href="http://jorkin.reallydo.com/upload/month_0909/1200992323614.jpg" rel="lightbox"><img alt="" src="http://jorkin.reallydo.com/upload/month_0909/1200992323614.jpg" border="0" /></a></p>
<p><strong><font style="BACKGROUND-COLOR: #999999" color="#ffffff">目前支持的库:</font></strong></p>
<ul>
    <li>jQuery </li>
    <li>MooTools </li>
    <li>The Dojo Toolkit </li>
    <li>Prototype </li>
    <li>Script.aculo.us </li>
    <li>Ext.JS </li>
    <li>Adobe Spry </li>
    <li>BBC Glow </li>
    <li>Yahoo UI! Library </li>
</ul>]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=650" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=650</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[心冷的时候看看]]></title>
	  <author>
		 <name>Jorkin</name>
		 <uri>http://Jorkin.Reallydo.Com/</uri>
		 <email>Jorkin2000(AT)hotmail.com</email>
	  </author>
	  <category term="" scheme="http://Jorkin.Reallydo.Com/default.asp?cateID=8" label="其它转载" /> 
	  <updated>2009-09-12T12:17:46+08:00</updated>
	  <published>2009-09-12T12:17:46+08:00</published>
		  <summary type="html"><![CDATA[<p>1<br />我是男教师。<br />痔疮犯了，垫了一片卫生巾（卫生巾是太太的）。<br />在学校打篮球的时候，那该死的东西顺着裤腿掉了出来，上边还有血~~~<br />球场周围围了很多学生看球，NND，拾也不是不拾也不行&hellip;&hellip;</p>
<p>2<br />高中的时候住校，有同学回家让他帮我捎点东西，便发短信：给我烧点衣服和钱。</p>
<p>3<br />昨晚煮螃蟹，水开后，我把螃蟹一个个扔进锅里。蟹子很新鲜，在锅里乱动。<br />老婆打小心善，就见不得这个，遂躲在我身后捂着眼睛不敢看。<br />我宽慰道：佳佳，我们是不是太残忍了？<br />老婆：嗯&hellip;&hellip;&hellip;&hellip;放盐了吗？</p>
<p>4<br />我们那个教化学的老头近视800度，一次上课在黑板上板书后转过身来突然指着我大喊：你站着干什么！！给我坐下！！<br />我当时正坐在最后一排的座位上，而我身后的墙上挂着我的大衣&hellip;&hellip;</p>
<p>5<br />上大学时急救课上，心肺复苏急救，教授边说边演示：<br />教授：双手按压胸部，不能使劲儿太大，压下2~3cm即可，劲儿太大容易把病人肋骨压断！<br />教授：下面请看示范（双手使劲儿一压），咔嚓一声！模型的肋骨断了。<br />尴尬的说，下课~</p>
<p>6<br />大学去深圳写生，<br />跟同学在马路上逛，突然一男同学往马路一边走去，<br />拍了一个人肩膀问：&ldquo;大哥，，请问&rdquo;，<br />是不是他脑子被门挤了，竟然问的是银行的押钞员！！<br />押钞员可能也没听清。<br />回过头来，<br />神经紧张的拿着枪（大喷）指着他：&ldquo;你要干嘛！要干嘛！&rdquo;，<br />我同学一看枪口对着自己，<br />吓的带着哭腔说：&ldquo;大哥，没别的意思，我就问问几点了&rdquo;。。。。。<br />爆瀑汗。。。。。。。</p>
<p>7<br />我在小学毕业时买了一本万恶的毕业册，因为上面说1月20日－2月18日的星座是 ----<br />水缸座<br />后来在很长一段时间内别人问我你是什么星座，我都说是水缸座！</p>
<p>8<br />跟以前同事一起下班，在公司对面马路往车站走，对面走来一个男人，盯着我看了一会，我刚想问他认识我吗。那人看了我一眼，接着吐了！那个囧啊！~~<br />那人是个醉汉！<br />我很无语，，同事笑喷了，从此此事流传千古开来。。。<br />同事逢人就说，***那个丑啊，那人看了她一眼就吐了。。。</p>
<p>9<br />我朋友有次喝醉了,据他妈说,他在厕所,右手拿电话状,左手按着镜子,和镜子中的&quot;入狱者&quot;深情对视道:吃得好不好啊?最近监狱管得严吗?争取早日出来啊...</p>
<p>10<br />有一次，因为有事要联系一个同学，但是手机里没存他的号码，于是给另外一个和他很熟的同学发短信，&ldquo;请问有 XXX 的电话号码吗？&rdquo;<br />然后耐心等候回复，5分钟后，终于收到回复了，迫不及待打开短信，赫然写着，&ldquo;有啊&rdquo;两个大字。<br />无奈之下，只能又再发短信给这位大哥，&ldquo;那么，请告诉我好吗？&rdquo;又继续等了五分钟，收到了回复，再次迫不及待地打开来看，赫然写着另外两个字，&ldquo;好啊&rdquo;！</p>
<p>11<br />我刚上大学的那会儿，特土，又一次课上老师让做ppt展示，以前从来没用过，正好那次我第一个上去讲，开了电脑半天投影仪没反应。<br />下面几个哥们喊按F2，按F2！<br />于是我犹豫了一下，问道：是俩键同时按吗？</p>
<p>12<br />一个小女孩跑到柜台前,对我说:&rsquo;阿姨,给我一包蕃茄酱.&rsquo;<br />我是男生,起码身份证上是这样写的.<br />于是我笑了笑,一边递给她一边对她说:&rsquo;没问题,小弟弟.&rsquo;<br />小女孩楞了一下:&rsquo;我不是小弟弟啊!&rsquo;<br />我:&rsquo;那我是阿姨吗?&rsquo;<br />小女孩接过蕃茄酱匆匆跑开了!</p>
<p>13<br />研究生毕业的时候，班上一个女生两个男生帮她从七楼将五大箱东西搬到一楼，累的那两个男生差点断气，看楼的阿姨看不<br />过去，说了一句让我感慨至今的话&ldquo;自己的男朋友不舍得用，别人的男朋友用得倒起劲&rdquo;。</p>
<p>14<br />某天出门时给好友打了一个电话，让她和我一起出来，然后我上公交车，顺便拨个电话给她：&ldquo;小M你到了吗？现在出门了吗？&rdquo;然后好友小M曰：&ldquo;我正做公交车呢！&rdquo;<br />我说：&ldquo;我坐的10X路公车，你坐哪个？&rdquo;好友大喜：&ldquo;我也是诶！&rdquo;<br />我感觉不对劲，看到对面的人看神经病一样看着我，下意识往后一看，发现好友小M坐在我身后的座位上：&ldquo;你到了吗？你到了吗？怎么不说话，喂.......&rdquo;</p>
<p>15<br />有一次乘坐45路去钟楼，中途上了位中年妇女。车上当时人不多，可她就是靠着我和另一个MM站着，我下意识地将自己的包包放在了身前，可旁边的MM却浑然不觉地<br />看着窗外。不久，那位中年妇女一只手伸进了MM的包包，说时迟那时快，我突然放了一个响屁，又臭又响啊，惹得满车人看我，羞得我恨不得找个洞钻啊。不过，熏<br />得中年妇女赶紧缩回了手去捂鼻子!哈哈!&rdquo;</p>
<p>16<br />大一时整个寝室的女生都很单纯，我们八个人都没见过安全套的实物长什么样。<br />某天晚上聊起来，就聚在电脑前搜图片，结果只搜到了包装盒和小包装没开封的那种图片，没有展开的那种，于是我们决定集体去路边那种投币机里买一个。<br />结果那些机器都是锈迹斑斑的，我们一堆人就围着那个箱子议论到底里面有没有东西、浪费一个硬币值不值之类，路人见了我们估计都很汗&hellip;&hellip;<br />后来终于买到一个，其中一女生大惊：&ldquo;这么小！&rdquo;我们都鄙视之，说带回寝室拆了再说。<br />打开后，我们中大多数都觉得跟自己想象的差不多，但是那个女生还是说：&ldquo;怎么这么小！那怎么把人罩起来？&rdquo;我们都被雷翻了，原来她以为安全套是要把整个人罩起来的&hellip;&hellip;<br />后来我们在超市看见一次性雨衣，都会对她说&ldquo;你的TT&rdquo;</p>
<p>17<br />俺们高中学校的德育主任，说话非常之强悍。<br />经典段落：现在我们学校有很不文明的现象，很多同学光着膀子打篮球，而且大部分是男生！<br />难道还有一小部分光着膀子的女生么？</p>
<p>18<br />高中一个同学近千度近视,没眼镜做不了人...<br />一次打球把眼镜给砸了还继续打,继续头三分...<br />结果还进了个空心...<br />全场都静了...<br />然后我(我和他不同队)捡起球扔给他开球...<br />然后他把球扔回给我,说:不是出界吗,你们开球...</p>
<p>19<br />视频：【电视剧】狙击手 第23集<br />评论：<br />酷6网友 IP:58.57.7.* 2009-08-16 22:08 发表<br />看了很多抗日题材的片子,怎么汉奸都是中国人.</p>
<p>20<br />一起练车的一个阿姨~~有天她老公骑摩托车载她回家~~在路上，有个男的想要拦住他们，对他们说~~我的车被前面的人偷走了，借你的车给我去追他~阿姨老公没理<br />他，继续开~那个阿姨坐在后面说了句~~~~我把我的车借给你了，我等下拿什么车去追你- -.....</p>
<p>21<br />一次和朋友喝酒，从下午喝到晚上，白的喝不动就全换成红酒了，最后我一手举着杯中酒一手拍着他的肩膀，刚要说掏心窝的话，他把嘴里以及为吸收的红酒全吐身<br />上了，他愣了一秒，抱头大哭，那就一个惨心裂肺，我无奈的说：&ldquo;不就吐了我一身吗，没事，咱谁跟谁，别哭&rdquo;，他抬起头对我说：&ldquo;X，我吐的是血，一定是得了<br />绝症了&hellip;&hellip;&rdquo;，我当时就无语了&hellip;&hellip;</p>
<p>22<br />小A公司近日发工资，小A高高兴兴的跑去了财务室去领工资，然后&hellip;&hellip;<br />会计说：&ldquo;你晚点来领工资吧，我这没零钱。&rdquo;</p>
<p>23<br />我一高中同学（MM）上大学后被学校派去宣传艾滋病日<br />顺便去跟着社团的人参加一个预防艾滋病的讲座<br />那天他们搬了凳子围教室坐一圈等老师来做演讲<br />这时候进来个人给每人轮流发了一根香蕉<br />我同学那个叫开心啊 嘿~听讲座还能吃水果 8错8错&middot;&middot;<br />她和旁边的人一边有说有笑的讲话 一边剥了香蕉皮吃的开心<br />这时候老师走进来 每人发了一个TT<br />原来那个香蕉是用来套TT用的 可是我同学手里只剩下一个香蕉皮。。</p>
<p>24<br />高一的时候,也快高考了,我们学校的高三肯定紧张的.周一升旗,有个高二女同学上屏幕演说:...各位学姐学长要认真面对高考,发挥自己最好的水平,不要再重复中考的失误...</p>
<p>25<br />化学老师 做稀盐酸和锌的实验 他把试管什么的准备好了 倒了点盐酸下去<br />等了半天没有反应 很纳闷 遂叫一同学回答 ：这位同学 你讲讲看为什么没有气泡产生呢？ 同学：老师，你没有放锌！ 老师：这位同学回答的很好！</p>
<p>26<br />中学的时候,开始流行文曲星,我同学有钱,就买了一个,98年的200块.<br />我想借他的玩会儿,玩到一个地方要求输密码,我就问他密码是多少.<br />他不说,他说不要看啦,个人资料.<br />于是,我就放弃了,但是我的好奇心一直没有消失过.<br />有一天,我看到他把文曲星拿出来玩,我无意中偷看到他在输密码,我看到他输了6个相同字符,心中窃喜,原来密码这么简单,于是找机会去翻来偷看.<br />于是,我一天趁他出去了,就把他的文曲星翻出来,赶紧输我看到那6个米字符******....</p>
<p>27<br />北京的公交车上，一男人带一四、五岁男孩。<br />等红绿灯时，公交车旁边有辆警车。<br />男人不知为什么那么恨pol.ice，跟男孩说：&ldquo;儿子，你看，他们是pol.ice。pol.ice知道么，他们都是人民的儿子。我就是人民，pol.ice就是我儿子！&rdquo;<br />1秒钟后，男孩大喊：&ldquo;那我是pol.ice他姥爷！&rdquo;<br />我们坐旁边的都没忍住，笑出声了。</p>
<p>28<br />我买了个乘车卡套<br />上面有个图案貌似是鸡<br />但我们又不确定是小鸡<br />他们就嘲笑我说我没有品位 买了个这么丑的东西<br />我很不服气 大声说 怎么了 鸡怎么了 鸡也是有尊严的（当时我正热衷于说xx也是有尊严的）<br />说完发现整个大厅的人都在看我...</p>
<p>29<br />一日。<br />死黨：&ldquo;我这是小蛮腰。&rdquo;<br />我不屑：&ldquo;你丫那是猪腰。&rdquo;<br />死黨不悦，反问：&ldquo;那你是什么腰？&rdquo;<br />答曰：&ldquo;人腰。&rdquo;</p>
<p>30<br />初中的时候，是两套独立的桌椅贴在一起放，和同桌（男）吵架了，然后我气呼呼的埋头把作业本写上名字，然后呼一下站起身来准备交作业，就看到我的<br />同桌坐在他的小凳子上，然后抱着他的小桌子。。整个朝外翻了下去。。。我惊呆了，不知道为什么，他缓缓挣扎着从自己的桌椅中爬起来，可怜巴巴地<br />说：我以为你要站起来打我T.T&hellip;&hellip;</p>
<p>31<br />前几天终于和从初中暗恋的帅哥哥出去约会了<br />我那个打扮呀~由于穿了很大领子的衣服，于是贴了胸贴...<br />很甜蜜的吃完饭,就在商业街散步.<br />突然,帅哥哥停下问我,你衣服下粘的是什么呀?<br />我茫茫然低头一看,OMG!胸贴居然滑掉了!并且粘在了衣服的下摆~<br />我很镇静地把它取下,扔进了垃圾桶:&quot;不知道是什么~估计是在哪儿粘的吧.&quot;<br />于是我们俩继续散步<br />而我的手,抱在胸前就再没有放下来... ...</p>
<p>32<br />在寝室聊八卦，一同学一边和我们聊天，一边用手剥手机充值卡的密码，越聊越起劲，等她回过神来，充值卡的密码那一条已经被她剥穿了，后来她用巧夺天工的手艺把废纸屑里密码刮了出来，还充值了。</p>
<p>33<br />有一次上体育课，老师一上来就板着脸严肃地宣布：今天，我要批评两位同学，是一男一女。站我后面的一男生嘀咕：狗男女！一对狗男女！老师大声说，我<br />说得就是你，你和XX（另一个女的）~~全班哄堂大笑~~</p>
<p>34<br />前几天手机上网看到一个新闻:歌手含笑吸毒被捕...<br />我就纳闷了...<br />吸毒就吸毒呗,为什么要含笑吸毒呢?<br />为什么新闻又要特别指出吸毒者含笑吸毒呢?<br />后来才知道,原来含笑是个歌手...</p>
<p>35<br />数年前，在公司做文秘，内急，慌忙冲向厕所，发现女厕所门虚掩着，因厕所为单坑，不敢贸然进入，遂敲门试探，只闻一女声从容答道：请进~~！！</p>
<p>36<br />我掏口袋的 时候，一把钥匙掉了，当时没有发现，后来回去找！<br />在路边有对小情侣在那里，男的 突然激动的说：是 谁的？到底是 谁的？<br />我当时以为是钥匙连忙说：我 的，我的！是我的<br />后来才知道，原来那女的怀孕了。。。。<br />可怜我的脸啊 。。。疼了几天</p>
<p>37<br />小时候年幼无知，只看过我妈穿胸罩，便以为胸罩是我妈专属的东西。于是有一段时间，我每天抱着撑衣竿子去院子里把所有的胸罩都收回家。邻居女人们日日来我家索要胸罩，我每天执着的守护着家门口，朝她们大喊，全是我妈的!~</p>
<p>38<br />我是一个搓澡的，我今天不小心把一个B社会老大的纹身搓没了</p>
<p>39<br />上学的时候学校是平房，九月份开学，来了好多新生。一天一个新生好像是课代表捧着一堆作业，问我：&ldquo;数学办公室在哪？&rdquo;<br />&ldquo;男厕边上。&rdquo;数学办公室确实在男厕边上，不过是左边。<br />那位老兄走到了男厕右边对着们喊&ldquo;报告&rdquo;<br />停顿了一下，里面传出 个声音&ldquo;不许进&rdquo;！<br />......</p>
<p>40<br />上小学的时候，晚上睡觉做梦，梦见和爸爸吵架，很气很气，居然气醒了。醒了之后看见旁边的爸爸，还是很火，上去啪啪两个嘴巴= =</p>
<p>41<br />一次数学晨练，全班都没做完。数学老师面露疑惑的说：我昨天晚上用广告时间就做完了，你们的速度也太慢了。有一同学当场不服，大叫道：老师看的是湖南台的广告<br />吧！全班笑倒。</p>
<p>42<br />新闻：佟大为妻子生下一女<br />评论：这个佟大真了不起</p>
<p>43<br />有一次去朋友家取东西 走到楼下 3人准备上楼 见楼下几个小孩在玩葵花点穴手<br />朋友多事 上去 说:看我的葵花点穴手 点到其中一个小孩<br />我们便上楼了 我们最少在楼上磨蹭了半个小时 下楼时 只见那个小孩仍在原地<br />一动不动 朋友上去 来了个葵花解穴手 小孩 便又活蹦乱跳<br />我狂汗.........................</p>
<p>44<br />早晨刚起床，在阳台上看到对面楼一女的只穿着文胸在做早饭。就喊老公过来看，老公铁青着脸，无语的把****的我拎回了屋里。</p>
<p>45<br />有个朋友忘了隐藏艳照门的pp，被他老爸看到，训他训到了一点多，第二天早上起来还接着训。<br />这个朋友忍无可忍，跟他妈说，我看这个怎么了，我都24了，是狗也该拉出去配种了！</p>
<p>46<br />某日在寝室电脑里看日本大顶(毛片)看到一半正好卡机了,事事就是这么巧,让我措手不及的是,学院生活部查寝室卫生的几个男女进了来！高喊着:&quot;查寝!&quot;当时定格的那个画面极其的不堪入目(也不知道日本的毛片这么变态)那时我极其紧张,汗都要出来咯!这几个人看着我和屏幕上的画面哑口无语......我看着他们大约10秒后胆怯的说:&quot;要 ~想 想批判它,就 得 得了解它!&quot;也不知道引用的是哪的话~<br />那几个人听后推门就走!再看看我寝室的哥们儿们乐疯咯!!我咣咣撞墙! 从那以后我就有了个外号&quot;批A先锋&quot;</p>
<p>47<br />昨天陪老婆逛街，从身边走前去一个美女，<br />老婆：&ldquo;老公，那MM不错哦，她穿的衣服也不错哦。&rdquo;<br />我：&ldquo;我去把他衣服扒了，衣服归你人归我。&rdquo;<br />MM好像听到了，回头看了我们俩口子10几秒。</p>
<p>48<br />朋友在路边看见一个卖毛片的小贩,过去询问价格,15块一张,于是买了两张.回家一看竟然是卡拉OK.朋友大怒,回去找,已无小贩踪影.决定每天在此蹲守,抓住后狠揍.几天后将小贩擒获.刚要动手,小贩哀求道:上次觉的您象pol.ice,所以不敢给真的.朋友问:现在可有真货.小贩说有,并且可以10块一张卖给他.朋友考虑后又给20拿了5张真的.回家一看,还是卡拉OK.那小贩再也找不着了</p>
<p>49<br />小时候刚学骑自行车，还不太会就跑到大街上，看到前面一个老大爷在走，自己感觉要撞上，就大叫，不要动，不要动。那个老大爷一下站在那里没有动，结果我拐来拐去  ，还是撞上了。老大爷站起来说，你瞄准呢。 当时尴尬死了。</p>
<p>50<br />一天看了蜡笔小新的漫画，想学他在身上画画，当然不可能完全照搬啦，退而求其次，在男朋友的胸前画了个naizhao，两个人笑得不亦乐乎，之后他也没洗澡，继续干别的事情。过了一会儿男朋友说要出去倒垃圾。倒垃圾的地方离家很远，要经过一个菜市场。十分钟后男朋友回来了，扑在我怀里猛哭。原来他是光着膀子出去的，经过菜市场的时候发现回头率奇高，正洋洋得意的时候猛然想起胸前还鲜明地展示着我的画作，以后没法混了！</p>
<p>51<br />初中时，一天正上课，忽听后排一声巨响，全班回头，看到后面一同学嘴唇红肿（酷似东城西就里的梁朝伟造型），并有n多塑料碎片插在上面~~~原来此君上课闲着没事，咬打火机玩，不料质量太差，爆了，</p>
<p>52<br />我朋友的糗事，是个女生。她考驾照的时候特别紧张，就怕过不了，手握方向盘握的特别紧。监考的看她紧张就说：别紧张！她回了句，我不紧张，他们说把监考的当条狗做在身边就行了</p>
<p>53<br />昨天下班途中,与同事闲聊,她说起她老公是属猪的,但是在年尾生的,算起来该算是猪尾巴, ... 马上头脑发热,一句让我悔恨终生的话,大声地,激动地,脱口而出了:&quot;我是猪头! ...</p>
<p>54<br />昨天在电梯里一开门，哇！全是帅哥！很优雅地走进去。正窃喜，一个两三岁的小女孩跑进电梯，冲我咧嘴一笑，大喊一声：妈妈！<br />我很镇定地、和蔼地弯下腰：&ldquo;小妹妹，你认错人了，我不是你妈妈。&rdquo;<br />电梯又开了，这次进来一条小狗，一进来就高兴地绕着我转，不停地摇尾巴，那个高兴劲！ 这我算没辙了。</p>
<p>55<br />有天我和一个好朋友上了公车上，前面都满了，就跑到后面，正好剩两个座位就坐下了，前排有两个中学生男孩，坐在那里。<br />走了一站，有一个20多岁的女的领着一个7,8岁的男孩上了车。（后来知道这是她孩子，：（）<br />没座位，于是站到了那两个中学生的旁边。没多久，小孩就闹开了，说腿疼。<br />那个中学生很识趣的站了起来，给小孩让座。<br />那个少妇就说：就让小孩做到你膝盖上吧。<br />中学生就答应了。小孩坐到了中学生的膝盖上。<br />又过了几站，上来了一个女孩。是那种及其漂亮的，而且穿的也是及其性感。<br />低胸，短裙。<br />公车开着开着，小孩突然冲着他妈妈喊了这么一句话：&ldquo;妈妈，哥哥的小鸡鸡在乱动！和爸爸的一样。&rdquo;<br />逛荡！<br />呵呵，车内骚动。<br />那中学生及其羞愧。拉着同学，然后就冲司机喊：<br />&ldquo;按铃！！&rdquo;（他是想喊开门，呵呵）<br />然后，就下车了。</p>]]></summary>
	  <link rel="alternate" type="text/html" href="http://Jorkin.Reallydo.Com/default.asp?id=649" /> 
	  <id>http://Jorkin.Reallydo.Com/default.asp?id=649</id> 
  </entry>	
		
</feed>