PostgreSQL Partitions
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的更多相关文章
- Spark SQL访问PostgreSQL
随着Spark SQL的正式发布,以及它对DataFrame的支持,它可能会取代HIVE成为越来越重要的针对结构型数据进行分析的平台.在博客文章What’s new for Spark SQL in ...
- PostgreSQL 传统 hash 分区方法和性能
背景 除了传统的基于trigger和rule的分区,PostgreSQL 10开始已经内置了分区功能(目前仅支持list和range),使用pg_pathman则支持hash分区. 从性能角度,目前最 ...
- PostgreSQL EXPLAIN执行计划学习--多表连接几种Join方式比较
转了一部分.稍后再修改. 三种多表Join的算法: 一. NESTED LOOP: 对于被连接的数据子集较小的情况,嵌套循环连接是个较好的选择.在嵌套循环中,内表被外表驱动,外表返回的每一行都要在内表 ...
- PostgreSQL 11 Partitioning Improvements
转自:https://pgdash.io/blog/partition-postgres-11.html PostgreSQL 11, due to be released later this ye ...
- PostgreSQL分区表实现——pg_pathman分区表管理
该博文用于自己学习记录,内容节选自: https://github.com/digoal/blog/blob/master/201610/20161024_01.md pg_pathman 创建分区表 ...
- PostgreSQL 分区索引演进
PostgreSQL 分区表,操作性相当便捷. 但只能在创建时决定是否为分区表,并决定分区条件字段,普通表创建后,不能在修改为分区表. Note:通过其他方法也可转化为分区表. 和其他数据库一样,分区 ...
- Distributed PostgreSQL on a Google Spanner Architecture – Storage Layer
转自:https://blog.yugabyte.com/distributed-postgresql-on-a-google-spanner-architecture-storage-layer/ ...
- 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 ...
- PostgreSQL 10.0 preview 性能增强 - 分区表性能增强(plan阶段加速)
标签 PostgreSQL , 10.0 , 分区表 , 子表 , 元信息搜索性能增强 背景 PostgreSQL 10.0 增强了分区表的子表搜索性能,对于涉及分区表包含子表特别多的QUERY,可以 ...
随机推荐
- 5 个 Composer 小技巧
Composer是新一代的PHP依赖管理工具.其介绍和基本用法可以看这篇<Composer PHP依赖管理的新时代>.本文介绍使用Composer的五个小技巧,希望能给你的PHP开发带来方 ...
- nginx安全相关设置
Nginx默认是显示版本号,隐藏 # vim nginx.conf 在http {—}里加上server_tokens off; 如: http { ……省略 server_tokens off; h ...
- 【转】设计模式(三)建造者模式Builder(创建型)
(http://blog.csdn.net/hguisu/article/details/7518060) 1. 概述 在软件开发的过程中,当遇到一个"复杂的对象"的创建工作,该对 ...
- 【转】Unity3D开发之Http协议网络通信
之前unity3d项目要做跟服务器通信的模块,然后服务器那边的协议是基于http的Jsonrpc通信方式一开始,用C#的本身类HttpWebRequest来提交请求,很快就在电脑上面成功了,代码也很简 ...
- Delphi 缩放图像代码 - 支持PNG透明通道
要求Delphi2007或者更高版本, 系统要求至少XP-SP2以上 实际上是利用了Windows的windowscodecs.dll这个文件的功能 在VCL里已经封装为TWICImage类 proc ...
- TEST指令
In the x86 assembly language, the TEST instruction performs a bitwise AND on two operands. The flags ...
- [LeetCode]题解(python):112 Path Sum
题目来源 https://leetcode.com/problems/path-sum/ Given a binary tree and a sum, determine if the tree ha ...
- Aptana快捷键(方便查询)
窗口类:Ctrl+ Shift +L 调出快捷键提示Ctrl+ W 关闭当前标签窗口Ctrl+ Shift + W 关闭当前标签窗口Ctrl+ F6 (或者是Aptana的Ctrl+Tab )下一个编 ...
- javac 错误: 编码GBK的不可映射字符
在java代码中有中文注释,使用javac编译时,出现编码报错. 错误: 编码GBK的不可映射字符 问题原因: 在编译的时候,如果我们没有用-encoding参数指定我们的JAVA源程序的编码格式,则 ...
- Java学习-011-创建文件实例及源代码
此文源码主要为应用 Java 创建文件的源代码.若有不足之处,敬请大神指正,不胜感激! 创建文件的源代码如下所示: /** * @function 文件操作:创建文件.若文件不存在,则直接创建文件:若 ...