why we need partitions

The first and most demanding reason to use partitions in a database is to increase the performance of the database. This is achieved by partition-wise joins; if a user’s queries perform a lot of full-table scans, partitioning will help vastly, because partitions will limit the scope of this search. The second important reason to partition is ease of managing large tables.

Partitioning always helps manage large objects. Although it is applicable to objects of any size, the advantages are more apparent in large tables. When a user recreates an index on a nonpartitioned table, the only option is to build the entire index in one statement. On the other hand, if the table is partitioned, the user can rebuild partitions of the local indexes one at a time.

PostgreSQL supports table partitioning through table inheritance, which means every

partition will be created as a child table of a single parent table. Partitioning is performed in such a way that every child table inherits a single parent table. The parent table will be empty; it exists just to describe the whole dataset. Currently in PostgreSQL, partitioning can be implemented in range partitioning or list partitioning.

Range partitioning can be done, for example, by record number ranges (such as record 0 to 100 or 100 to 200) or even using date ranges (such as from 2014-11-01 to 2014-11-30).

List partitioning can be done, for example, by a list of cities (such as New York, Boston,

Chicago, and Houston) or list of departments (such as HR, finance, administration, and so on).

There are five simple steps used to create a partition in PostgreSQL, which are as follows:

1. Create the master table.

2. Create multiple child tables without having an overlapped table constraint.

3. Create indexes.

4. Create a trigger function to insert data into child tables.

5. Enable the constraint exclusion.

Range partition

The range partition is the partition in which we partition a table into ranges defined by a single column or multiple columns. When defining the ranges, the user will have to take care that ranges should be connected and not overlapping with each other; moreover, ranges must be defined using the < value operator. For instance, one can partition by date ranges or ranges of identifiers for specific business objects.

Creating the master table

[postgres@minion1 bin]$ ./psql

psql (9.4.5)

Type "help" for help.

postgres=# create database partition_db;

CREATE DATABASE

postgres=# \c partition_db

You are now connected to database "partition_db" as user "postgres".

partition_db=# create database warehouse_db;

CREATE DATABASE

partition_db=# \c warehouse_db

You are now connected to database "warehouse_db" as user "postgres".

warehouse_db=# CREATE TABLE sales_record

warehouse_db-# (

warehouse_db(# id NUMERIC PRIMARY KEY,

warehouse_db(# sales_amount NUMERIC,

warehouse_db(# sales_date DATE NOT NULL DEFAULT CURRENT_DATE

warehouse_db(# );

CREATE TABLE

Creating a range partition table

Each partition will have two months’ data.

Create the sales_record_m1_to_m2 child table as follows:

warehouse_db=# CREATE TABLE sales_record_m1_to_m2

warehouse_db-# (

warehouse_db(# PRIMARY KEY (id, sales_date),

warehouse_db(# CHECK (sales_date >= DATE '2015-01-01'

warehouse_db(# AND sales_date < DATE '2015-03-01')

warehouse_db(# )

warehouse_db-# INHERITS (sales_record);

CREATE TABLE

This child table will contain data of January and February.

Now, create the sales_record_m3_to_m4 child table as follows:

warehouse_db=# CREATE TABLE sales_record_m3_to_m4

warehouse_db-# (

warehouse_db(# PRIMARY KEY (id, sales_date),

warehouse_db(# CHECK (sales_date >= DATE '2015-03-01'

warehouse_db(# AND sales_date < DATE '2015-05-01')

warehouse_db(# )

warehouse_db-# INHERITS (sales_record);

CREATE TABLE

This child table will contain data of March and April.

Create the sales_record_m5_to_m6 child table as follows:

warehouse_db=# CREATE TABLE sales_record_m5_to_m6

warehouse_db-# (

warehouse_db(# PRIMARY KEY (id, sales_date),

warehouse_db(# CHECK (sales_date >= DATE '2015-05-01'

warehouse_db(# AND sales_date < DATE '2015-07-01')

warehouse_db(# )

warehouse_db-# INHERITS (sales_record);

CREATE TABLE

This child table will contain data of May and June.

Create the sales_record_m7_to_m8 child table as follows:

warehouse_db=# CREATE TABLE sales_record_m7_to_m8

warehouse_db-# (

warehouse_db(# PRIMARY KEY (id, sales_date),

warehouse_db(# CHECK (sales_date >= DATE '2015-07-01'

warehouse_db(# AND sales_date < DATE '2015-09-01')

warehouse_db(# )

warehouse_db-# INHERITS (sales_record);

CREATE TABLE

This child table will contain data of July and August.

Create the sales_record_m9_to_m10 child table as follows:

warehouse_db=# CREATE TABLE sales_record_m9_to_m10

warehouse_db-# (

warehouse_db(# PRIMARY KEY (id, sales_date),

warehouse_db(# CHECK (sales_date >= DATE '2015-09-01'

warehouse_db(# AND sales_date < DATE '2015-11-01')

warehouse_db(# )

warehouse_db-# INHERITS (sales_record);

CREATE TABLE

This child table will contain data of September and October.

Now, create the sales_record_m11_to_m12 child table as follows:

warehouse_db=# CREATE TABLE sales_record_m11_to_m12

warehouse_db-# (

warehouse_db(# PRIMARY KEY (id, sales_date),

warehouse_db(# CHECK (sales_date >= DATE '2015-11-01'

warehouse_db(# AND sales_date < DATE '2016-01-01')

warehouse_db(# )

warehouse_db-# INHERITS (sales_record);

CREATE TABLE

This child table will contain data of November and December.

Verifing that the tables are linked and the partition is successfully created using the following query:

warehouse_db=# \d+ sales_record

Table "public.sales_record"

Column    |  Type   |              Modifiers               | Storage | Stats target | Description

--------------+---------+--------------------------------------+---------+--------------+-------------

id           | numeric | not null                             | main    |              |

sales_amount | numeric |                                      | main    |              |

sales_date   | date    | not null default ('now'::text)::date | plain   |              |

Indexes:

"sales_record_pkey" PRIMARY KEY, btree (id)

Child tables: sales_record_m11_to_m12,

sales_record_m1_to_m2,

sales_record_m3_to_m4,

sales_record_m5_to_m6,

sales_record_m7_to_m8,

sales_record_m9_to_m10

Creating an index on child tables

Now, we are going to create indexes on child tables to speed up the sales_day field usage, using almost all queries (INSERT, SELECT, and UPDATE) on the date field.

Create the m1_to_m2_sales_date index on the sales_record_m1_to_m2 child table as follows:

warehouse_db=# CREATE INDEX m1_to_m2_sales_date ON sales_record_m1_to_m2

warehouse_db-# (sales_date);

CREATE INDEX

Create the m3_to_m4_sales_date index on the sales_record_m3_to_m4 child table as

follows:

warehouse_db=# CREATE INDEX m3_to_m4_sales_date ON sales_record_m3_to_m4

warehouse_db-# (sales_date);

CREATE INDEX

Now, let’s create the m5_to_m6_sales_date index on the sales_record_m5_to_m6 child table:

warehouse_db=# CREATE INDEX m5_to_m6_sales_date ON sales_record_m5_to_m6

warehouse_db-# (sales_date);

CREATE INDEX

Create the m7_to_m8_sales_date index on the sales_record_m7_to_m8 child table as

follows:

warehouse_db=# CREATE INDEX m7_to_m8_sales_date ON sales_record_m7_to_m8

warehouse_db-# (sales_date);

CREATE INDEX

Then, create the m9_to_m10_sales_date index on the sales_record_m9_to_m10 child table as follows:

warehouse_db=# CREATE INDEX m9_to_m10_sales_date ON sales_record_m9_to_m10

warehouse_db-# (sales_date);

CREATE INDEX

Create the m11_to_m12_sales_date index on the sales_record_m11_to_m12 child table as follows:

warehouse_db=# CREATE INDEX m11_to_m12_sales_date ON

warehouse_db-# sales_record_m11_to_m12 (sales_date);

CREATE INDEX

Creating a trigger on the master table

Conditions must be exactly the same as what the child tables check.

creating a trigger function using the following syntax:

warehouse_db=# CREATE OR REPLACE FUNCTION sales_record_insert()

warehouse_db-# RETURNS TRIGGER AS $$

warehouse_db$# BEGIN

warehouse_db$# IF (NEW.sales_date >= DATE '2015-01-01' AND NEW.sales_date < DATE '2015-03-01') THEN

warehouse_db$# INSERT INTO sales_record_m1_to_m2 VALUES (NEW.*);

warehouse_db$# ELSEIF (NEW.sales_date >= DATE '2015-03-01' AND NEW.sales_date < DATE '2015-05-01') THEN

warehouse_db$# INSERT INTO sales_record_m3_to_m4 VALUES (NEW.*);

warehouse_db$# ELSEIF (NEW.sales_date >= DATE '2015-05-01' AND NEW.sales_date < DATE '2015-07-01') THEN

warehouse_db$# INSERT INTO sales_record_m5_to_m6 VALUES (NEW.*);

warehouse_db$# ELSEIF (NEW.sales_date >= DATE '2015-07-01' AND NEW.sales_date < DATE '2015-09-01') THEN

warehouse_db$# INSERT INTO sales_record_m7_to_m8 VALUES (NEW.*);

warehouse_db$# ELSEIF (NEW.sales_date >= DATE '2015-09-01' AND NEW.sales_date < DATE '2015-11-01') THEN

warehouse_db$# INSERT INTO sales_record_m9_to_m10 VALUES (NEW.*);

warehouse_db$# ELSEIF (NEW.sales_date >= DATE '2015-11-01' AND NEW.sales_date < DATE '2016-01-01') THEN

warehouse_db$# INSERT INTO sales_record_m11_to_m12 VALUES (NEW.*);

warehouse_db$# ELSE

warehouse_db$# RAISE EXCEPTION 'Date is out of range. Something is wrong with sales_record_insert_trigger() function';

warehouse_db$# END IF;

warehouse_db$# RETURN NULL;

warehouse_db$# END;

warehouse_db$# $$LANGUAGE plpgsql;

CREATE FUNCTION

This function will simply populate the data in the respective child table on the basis of the sales_date condition.

Now, the supportive trigger will call the preceding trigger function automatically

whenever a user uses the INSERT, UPDATE, or DELETE operations on data in the master table. Creating the supportive trigger in the following manner:

warehouse_db=# CREATE TRIGGER sales_day_trigger

warehouse_db-# BEFORE INSERT ON sales_record

warehouse_db-# FOR EACH ROW

warehouse_db-# EXECUTE PROCEDURE sales_record_insert();

CREATE TRIGGER

Enabling the constraint exclusion

The final step in implementation of partitioning is enabling the constraint exclusion.Constraint exclusion is backed by the CHECK constraints that we have used in our child table’s CREATE syntax. Do remember that if the constraint exclusion is disabled, then our

queries will not use CHECK constraints, and as a result, every query scan will be done on all the child tables and thus will reduce performance; this is why constraint exclusion to is very important when using partitioned tables.

The steps to enable constraint exclusion are as follows:

1. Open the postgresql.conf file that is present in the data directory on your default installation path. In most cases, it is /usr/local/pgsql/data.

2. Set constraint exclusion on with the following row in postgresql.conf:

constraint_exclusion = on

Alternatively, you can set constraint exclusion to on using the following command on

psql:

warehouse_db=# SET constraint_exclusion = on;

Congratulations! Finally, the master table is available for the DML and DDL operations,and all the INSERT, SELECT and DELETE operations go to the child tables by date.

Performing DML operations on a partition table

When a user inserts a row in the master table, our trigger sales_day_trigger will be triggered, and it will call our sales_record_insert() trigger function, and based on sales_date, the insertion will be made to a specific child table. Now, let’s insert a few records into the sales_record table.We will then perform the SELECT statements to verify that records are properly populated in child tables. This can be done in the following manner:

warehouse_db=# INSERT INTO sales_record

(id, sales_amount, sales_date)

VALUES

(1, 500, TO_DATE('02/12/2015','MM/DD/YYYY'));

INSERT 0 0

warehouse_db=# INSERT INTO sales_record

warehouse_db-# (id, sales_amount, sales_date)

warehouse_db-# VALUES

warehouse_db-# (2, 1500, TO_DATE('03/10/2015','MM/DD/YYYY'));

INSERT 0 0

warehouse_db=# INSERT INTO sales_record

warehouse_db-# (id, sales_amount, sales_date)

warehouse_db-# VALUES

warehouse_db-# (3, 2500, TO_DATE('05/15/2015','MM/DD/YYYY'));

INSERT 0 0

warehouse_db=# INSERT INTO sales_record

warehouse_db-# (id, sales_amount, sales_date)

warehouse_db-# VALUES

warehouse_db-# (4, 2000, TO_DATE('07/25/2015','MM/DD/YYYY'));

INSERT 0 0

warehouse_db=# INSERT INTO sales_record

warehouse_db-# (id, sales_amount, sales_date)

warehouse_db-# VALUES

warehouse_db-# (5, 2200, TO_DATE('09/15/2015','MM/DD/YYYY'));

INSERT 0 0

warehouse_db=# INSERT INTO sales_record

warehouse_db-# (id, sales_amount, sales_date)

warehouse_db-# VALUES

warehouse_db-# (6, 1200, TO_DATE('11/15/2015','MM/DD/YYYY'));

INSERT 0 0

We have inserted six records, and we are now going to perform the SELECT queries on our child tables to verify that our child tables get the right data. Let’s do a SELECT operation on the sales_record_m3_to_m4 table in the following manner:

warehouse_db=# SELECT * FROM sales_record_m3_to_m4;

id | sales_amount | sales_date

----+--------------+------------

2 |         1500 | 2015-03-10

(1 row)

Let’s do a select operation on the sales_record_m9_to_m10 table in the following

manner:

warehouse_db=# SELECT * FROM sales_record_m9_to_m10;

id | sales_amount | sales_date

----+--------------+------------

5 |         2200 | 2015-09-15

(1 row)

As you can see in the preceding result, the sales_record_m9_to_m10 child table contains the record that has sales_date for September and October.

A SELECT operation on the parent/master table will grab data from all child tables. This can be seen using the following statement:

warehouse_db=# SELECT * FROM sales_record;

id | sales_amount | sales_date

----+--------------+------------

1 |          500 | 2015-02-12

2 |         1500 | 2015-03-10

3 |         2500 | 2015-05-15

4 |         2000 | 2015-07-25

5 |         2200 | 2015-09-15

6 |         1200 | 2015-11-15

(6 rows)

Handling the UPDATE and DELETE statements on a partition table

We don’t need any UPDATE or DELETE triggers, the INSERT trigger is self-sufficient to handle the UPDATE or DELETE statement as well. First, let’s perform an UPDATE action and verify the impact on the child table in the following manner:

warehouse_db=# UPDATE sales_record SET sales_date='2015-9-13' WHERE id = 5;

UPDATE 1

The preceding query will update the record of the date 2015-9-15 with id = 5.

Let’s perform a SELECT operation to verify the update of the record in the following

manner:

warehouse_db=# SELECT * FROM sales_record_m9_to_m10;

id | sales_amount | sales_date

----+--------------+------------

5 |         2200 | 2015-09-13

(1 row)

We can now verify that the record is updated and sales_date is changed to a new date,that is, 2015-09-13.

An update on a table that can cause row movement between children requires an UPDATE trigger.

Now, let’s perform a simple DELETE operation and verify the impact on partitioned tables:

warehouse_db=# DELETE FROM sales_record where sales_date = '2015-9-13';

DELETE 1

warehouse_db=# SELECT * FROM sales_record_m9_to_m10;

id | sales_amount | sales_date

----+--------------+------------

(0 rows)

Since the SELECT statement did not return any record, this confirms that we have successfully deleted the record with sales_date = '2015-9-13'.

List partition

List partition is very much similar to range partition. The table is partitioned by explicitly listing which key values appear in each partition. In list partition, each partition is defined and designated based on a column value in one set of value lists, instead of one set of adjoining ranges of values. This will be done by defining each partition by means of the values IN (value_list) syntax, where value_list is a comma-separated list of values.

We will create a master table that will have a sales record along with the city information. The list partition will use the city column as a base to create the child partitions. Let’s create a master table first in the following manner:

warehouse_db=# CREATE TABLE sales_record_listpart

warehouse_db-# (

warehouse_db(# id NUMERIC primary key,

warehouse_db(# sales_date date,

warehouse_db(# sales_amount NUMERIC,

warehouse_db(# city text

warehouse_db(# );

CREATE TABLE

Now, let’s create the child tables on the basis of the city list.

Create the sales_record_list1 table in the following manner:

warehouse_db=# CREATE TABLE sales_record_list1

warehouse_db-# (

warehouse_db(# PRIMARY KEY (id, city),

warehouse_db(# CHECK (city IN ('new york', 'sydney'))

warehouse_db(# )

warehouse_db-# INHERITS (sales_record_listpart);

CREATE TABLE

Now, create the sales_record_list2 table in the following manner:

warehouse_db=# CREATE TABLE sales_record_list2

warehouse_db-# (

warehouse_db(# PRIMARY KEY (id, city),

warehouse_db(# CHECK (city IN ('Islamabad', 'Boston', 'London'))

warehouse_db(# )

warehouse_db-# INHERITS (sales_record_listpart);

CREATE TABLE

Let’s create the index for the sales_record_list1 table:

warehouse_db=# CREATE INDEX list1_index ON sales_record_list1(city);

CREATE INDEX

Let’s create the index for the sales_record_list2 table:

warehouse_db=# CREATE INDEX list2_index ON sales_record_list2 (city);

CREATE INDEX

Now, create the trigger function in the following manner:

warehouse_db=# CREATE OR REPLACE FUNCTION sales_record_list_insert()

warehouse_db-# RETURNS TRIGGER AS $$

warehouse_db$# BEGIN

warehouse_db$# IF (NEW.city IN ('new york', 'sydney')) THEN

warehouse_db$# INSERT INTO sales_record_list1 VALUES (NEW.*);

warehouse_db$# ELSEIF (NEW.city IN ('Islamabad', 'Boston', 'London')) THEN

warehouse_db$# INSERT INTO sales_record_list2 VALUES (NEW.*);

warehouse_db$# ELSE

warehouse_db$# RAISE EXCEPTION 'CITY not present in this lists';

warehouse_db$# END IF;

warehouse_db$# RETURN NULL;

warehouse_db$# END;

warehouse_db$# $$LANGUAGE plpgsql;

CREATE FUNCTION

In the end, we need to create the supporting trigger in the following manner:

warehouse_db=# CREATE TRIGGER sales_day_trigger

warehouse_db-# BEFORE INSERT ON sales_record_listpart

warehouse_db-# FOR EACH ROW

warehouse_db-# EXECUTE PROCEDURE sales_record_list_insert();

CREATE TRIGGER

Verifing that the partition is linked with the master table using the following

command:

warehouse_db=# \d+ sales_record_listpart

Table "public.sales_record_listpart"

Column    |  Type   | Modifiers | Storage  | Stats target | Description

--------------+---------+-----------+----------+--------------+-------------

id           | numeric | not null  | main     |              |

sales_date   | date    |           | plain    |              |

sales_amount | numeric |           | main     |              |

city         | text    |           | extended |              |

Indexes:

"sales_record_listpart_pkey" PRIMARY KEY, btree (id)

Triggers:

sales_day_trigger BEFORE INSERT ON sales_record_listpart FOR EACH ROW EXECUTE PROCEDURE sales_record_list_insert()

Child tables: sales_record_list1,

sales_record_list2

Now, let’s do some quick inserts and verify that our list partition is also working how we expect it do so:

warehouse_db=# INSERT INTO sales_record_listpart

warehouse_db-# (id, sales_date, sales_amount, city)

warehouse_db-# VALUES

warehouse_db-# (1,'15-APR-2008',1200,'sydney');

INSERT 0 0

warehouse_db=# INSERT INTO sales_record_listpart

warehouse_db-# (id, sales_date, sales_amount, city)

warehouse_db-# VALUES

warehouse_db-# (2,'15-APR-2008',1500,'Boston');

INSERT 0 0

warehouse_db=# INSERT INTO sales_record_listpart

warehouse_db-# (id, sales_date, sales_amount, city)

warehouse_db-# VALUES

warehouse_db-# (3,'16-APR-2008',1800,'Islamabad');

INSERT 0 0

warehouse_db=# INSERT INTO sales_record_listpart

warehouse_db-# (id, sales_date, sales_amount, city)

warehouse_db-# VALUES

warehouse_db-# (4,'20-APR-2008',1300,'new york');

INSERT 0 0

When you perform the preceding INSERT statements, you will observe that the INSERT query returns the INSERT 0 0 message; this is because the record is inserted in the child tables instead of the master tables.

Perform SELECT on salse_record_list1 to verify that the record is inserted as expected in the following manner:

warehouse_db=# SELECT * FROM sales_record_list1;

id | sales_date | sales_amount |   city

----+------------+--------------+----------

1 | 2008-04-15 |         1200 | sydney

4 | 2008-04-20 |         1300 | new york

(2 rows)

Perform SELECT on sales_record_list2 to verify that the record is inserted as expected in the following manner:

warehouse_db=# SELECT * FROM sales_record_list2;

id | sales_date | sales_amount |   city

----+------------+--------------+-----------

2 | 2008-04-15 |         1500 | Boston

3 | 2008-04-16 |         1800 | Islamabad

(2 rows)

Perform SELECT on sales_record_listpart to verify that the record is inserted as expected in the following manner:

warehouse_db=# SELECT * FROM sales_record_listpart;

id | sales_date | sales_amount |   city

----+------------+--------------+-----------

1 | 2008-04-15 |         1200 | sydney

4 | 2008-04-20 |         1300 | new york

2 | 2008-04-15 |         1500 | Boston

3 | 2008-04-16 |         1800 | Islamabad

(4 rows)

PostgreSQL Partitions的更多相关文章

  1. Spark SQL访问PostgreSQL

    随着Spark SQL的正式发布,以及它对DataFrame的支持,它可能会取代HIVE成为越来越重要的针对结构型数据进行分析的平台.在博客文章What’s new for Spark SQL in ...

  2. PostgreSQL 传统 hash 分区方法和性能

    背景 除了传统的基于trigger和rule的分区,PostgreSQL 10开始已经内置了分区功能(目前仅支持list和range),使用pg_pathman则支持hash分区. 从性能角度,目前最 ...

  3. PostgreSQL EXPLAIN执行计划学习--多表连接几种Join方式比较

    转了一部分.稍后再修改. 三种多表Join的算法: 一. NESTED LOOP: 对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择.在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表 ...

  4. PostgreSQL 11 Partitioning Improvements

    转自:https://pgdash.io/blog/partition-postgres-11.html PostgreSQL 11, due to be released later this ye ...

  5. PostgreSQL分区表实现——pg_pathman分区表管理

    该博文用于自己学习记录,内容节选自: https://github.com/digoal/blog/blob/master/201610/20161024_01.md pg_pathman 创建分区表 ...

  6. PostgreSQL 分区索引演进

    PostgreSQL 分区表,操作性相当便捷. 但只能在创建时决定是否为分区表,并决定分区条件字段,普通表创建后,不能在修改为分区表. Note:通过其他方法也可转化为分区表. 和其他数据库一样,分区 ...

  7. Distributed PostgreSQL on a Google Spanner Architecture – Storage Layer

    转自:https://blog.yugabyte.com/distributed-postgresql-on-a-google-spanner-architecture-storage-layer/ ...

  8. PostgreSQL逻辑复制到kafka-实践

    kafka 安装 wget http://mirror.bit.edu.cn/apache/kafka/2.3.0/kafka_2.12-2.3.0.tgz cp kafka_2.12-2.0.1.t ...

  9. PostgreSQL 10.0 preview 性能增强 - 分区表性能增强(plan阶段加速)

    标签 PostgreSQL , 10.0 , 分区表 , 子表 , 元信息搜索性能增强 背景 PostgreSQL 10.0 增强了分区表的子表搜索性能,对于涉及分区表包含子表特别多的QUERY,可以 ...

随机推荐

  1. Memcached原理深度分析详解

    Memcached是 danga.com(运营LiveJournal的技术团队)开发的一套分布式内存对象缓存系统,用于在动态系统中减少数据库负载,提升性能.关于这个东 西,相信很多人都用过,本文意在通 ...

  2. improve performance whilemaintaining the functionality of a simpler and more abstract model design of processor hardware

    Computer Systems A Programmer's Perspective Second Edition In this chapter, we take a brief look at ...

  3. js制作带有遮罩弹出层实现登录小窗口

    要实现的效果如下 点击“登录”按钮后,弹出登录小窗口,并且有遮罩层(这个名词还是百度知道的,以前只知道效果,却不知道名字) 在没有点击“登录”按钮之前登录小窗口不显示,点击“登录”按钮后小窗口显示,并 ...

  4. php面向对象之__toString()

    似曾相识,在php面向对象编程之魔术方法__set,曾经介绍了什么是魔术方法,这一章又介绍一个魔术方法__tostring(). __toString()是快速获取对象的字符串信息的便捷方式,似乎魔术 ...

  5. Windows与Linux共享文件夹互相访问

    [原文]  首先安装并配置软件samba [html] view plain copy sudo yum install samba samba-client vim /etc/samba/smb.c ...

  6. 【转】Eclipse Class Decompiler——Java反编译插件

    闲暇之余,写了一个Eclipse下的Java反编译插件:Eclipse Class Decompiler,整合了目前最好的2个Java反编译工具Jad和JD-Core,并且和Eclipse Class ...

  7. Archiver 浅析

    归档是一个过程,即用某种格式来保存一个或多个对象,以便以后还原这些对象.通常,这个过程包括将(多个)对象写入文件中,以便以后读取该对象. 两种归档数据的方法:属性列表和带键值的编码. 属性列表局限性很 ...

  8. 轮询、select、 epoll

    网卡设备对应一个中断号, 当网卡收到网络端的消息的时候会向CPU发起中断请求, 然后CPU处理该请求. 通过驱动程序 进而操作系统得到通知, 系统然后通知epoll, epoll通知用户代码.  一. ...

  9. 【Android测试】【随笔】与 “美丽说” 测试同事交流

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5405432.html 分享者简介 雪晗,3年+测试经验,现 ...

  10. C/C++获取系统时间

    C/C++获取系统时间需要使用Windows API,包含头文件"windows.h". 系统时间的数据类型为SYSTEMTIME,可以在winbase.h中查询到如下定义: ty ...