PostgreSQL从继承到分区(二)

Stella981
• 阅读 663

二、Partitioning_table

2.1 关于分区表

借助表的继承特性PostgreSQL实现了分区表功能,虽然相比Oracle、MySQL的分区表来说其实现过程比较麻烦,但是这种方式同样能达到分区的效果,而且对大表的查询优化效果很明显。

PostgreSQL的分区表概念与其它数据库的分区表概念相同,都是将逻辑上的一个大表分割成物理上的多个子块。分区带来的不仅仅是访问性能上的提升,而且还可以使管理与维护变得更加方便、简单。

表分区的优点:

  • 可以显著提升表的查询性能,尤其是当频繁的查询访问发生在一个单一的分区上时,性能的提升效果将会非常显著;

  • 分区减小了每个块上的索引大小,使之前由于整个数据集上的索引过大而无法完全放入内存中导致读写操作产生大量的磁盘访问的问题得到改善;

  • 当查询或更新大量发生在单一分区上时,可以通过发挥分区上顺序扫描的优点来提升性能,进而代替使用索引随机访问读取整个表;

  • 批量加载或删除可通过添加或删除分区来完成。使用ALTER TABLE NO INHERIT和DROP TABLE远远要比批量操作快得多,此类命令避免了由于批量DELETE而引发的VACUUM额外开销;

  • 可以将很少用到的数据移到便宜的、速度慢的存储介质上去。

通常建议当表的大小超过了服务器物理内存的时候创建分区表,但是究竟哪个表在分区策略中受益最终取决于应用程序。

目前,PostgreSQL没有单独的分区表功能,而是通过表继承的方式来实现该功能,每个分区被创建为一个唯一父表的子表,父表中通常不存放数据,它的存在只是为了代表整个数据集。

PostgreSQL目前支持的分区类型:Range Partitioning(范围分区)、List Partitioning(列表分区)

范围分区:表被一个或多个键字字段分区成“范围”,范围中不重叠的数值分布到不同的分区里。

列表分区:明确地列出每个分区里应该出现哪些键字值。

组合分区:将现有分区类型组合使用(先范围再列表)。

2.2 分区表实例

2.2.1 范围分区实例

创建主表:

part=# create table people(id int not null,name varchar(20) not null,logdate date not null);
CREATE TABLE

创建分区表:

part=# create table people_y2013m12( check( logdate >= DATE '2013-12-01' AND logdate < DATE '2014-01-01' ) ) inherits(people);
CREATE TABLE
part=# create table people_y2014m01( check( logdate >= DATE '2014-01-01' AND logdate < DATE '2014-02-01' ) ) inherits(people);
CREATE TABLE
part=# create table people_y2014m02( check( logdate >= DATE '2014-02-01' AND logdate < DATE '2014-03-01' ) ) inherits(people);
CREATE TABLE

为分区表创建索引:

part=# create index people_y2013m12_logdate on people_y2013m12(logdate);
CREATE INDEX
part=# create index people_y2014m01_logdate on people_y2014m01(logdate);
CREATE INDEX
part=# create index people_y2014m02_logdate on people_y2014m02(logdate);
CREATE INDEX

建立触发器函数:

part=# create or replace function people_insert_trigger()
part-# returns trigger as $$
part$# begin
part$#   if (new.logdate >= DATE '2013-12-01' and
part$#       new.logdate < DATE '2014-01-01') then
part$#      insert into people_y2013m12 values (new.*);
part$#   elsif (new.logdate >= DATE '2014-01-01' and
part$#          new.logdate < DATE '2014-02-01') then
part$#         insert into people_y2014m01 values (new.*);
part$#   elsif (new.logdate >= DATE '2014-02-01' and
part$#          new.logdate < DATE '2014-03-01') then
part$#         insert into people_y2014m02 values (new.*);
part$#   else
part$#         RAISE EXCEPTION 'Date out of range.  Fix the people_insert_trigger() function!';
part$#   end if;
part$#   return null;
part$# end;
part$# $$
part-# language plpgsql;
CREATE FUNCTION

创建触发器:

part=# CREATE TRIGGER insert_people_trigger
part-#   BEFORE INSERT ON people
part-#   FOR EACH ROW EXECUTE PROCEDURE people_insert_trigger();
CREATE TRIGGER

查看主表信息:

part=# \d+ people
                                Table "public.people"
 Column  |         Type          | Modifiers | Storage  | Stats target | Description 
---------+-----------------------+-----------+----------+--------------+-------------
 id      | integer               | not null  | plain    |              | 
 name    | character varying(20) | not null  | extended |              | 
 logdate | date                  | not null  | plain    |              | 
Triggers:
    insert_people_trigger BEFORE INSERT ON people FOR EACH ROW EXECUTE PROCEDURE people_insert_trigger()
Child tables: people_y2013m12,
              people_y2014m01,
              people_y2014m02
Has OIDs: no

测试:

part=# insert into people values (1,'lian1','2013-12-10');
INSERT 0 0
part=# insert into people values (2,'lian2','2014-01-10');
INSERT 0 0
part=# insert into people values (3,'lian3','2014-02-10');
INSERT 0 0
part=# insert into people values (4,'lian4','2014-03-10');
ERROR:  Date out of range.  Fix the people_insert_trigger() function!
STATEMENT:  insert into people values (4,'lian4','2014-03-10');
ERROR:  Date out of range.  Fix the people_insert_trigger() function!

查看数据及数据在分区上的具体分布:

part=# select * from people;
 id | name  |  logdate   
----+-------+------------
  1 | lian1 | 2013-12-10
  2 | lian2 | 2014-01-10
  3 | lian3 | 2014-02-10
(3 rows)
part=# SELECT p.relname,c.*  FROM people c, pg_class p WHERE c.tableoid = p.oid;
     relname     | id | name  |  logdate   
-----------------+----+-------+------------
 people_y2013m12 |  1 | lian1 | 2013-12-10
 people_y2014m01 |  2 | lian2 | 2014-01-10
 people_y2014m02 |  3 | lian3 | 2014-02-10
(3 rows)

2.2.2 列表分区实例

创建主表:

list=# create table customer(id int,name varchar(20),city varchar(30));
CREATE TABLE

创建分区表:

list=# create table customer_sd( check(city in ('jinan','qingdao','weifang','zibo')) ) inherits(customer);
CREATE TABLE
list=# create table customer_sx( check(city in ('xian','xianyang','weinan','baoji')) ) inherits(customer);
CREATE TABLE

查看主表结构信息:

list=# \d+ customer
                              Table "public.customer"
 Column |         Type          | Modifiers | Storage  | Stats target | Description 
--------+-----------------------+-----------+----------+--------------+-------------
 id     | integer               |           | plain    |              | 
 name   | character varying(20) |           | extended |              | 
 city   | character varying(30) |           | extended |              | 
Child tables: customer_sd,
              customer_sx
Has OIDs: no

为分区表创建索引:

list=# create index customer_sd_city on customer_sd(city);
CREATE INDEX
list=# create index customer_sx_city on customer_sx(city);
CREATE INDEX

创建触发器函数:

list=# create or replace function customer_insert_trigger()
list-# returns trigger as $$
list$# begin
list$#   if (new.city in ('jinan','qingdao','weifang','zibo')) then
list$#      insert into customer_sd values (new.*);
list$#   elsif (new.city in ('xian','xianyang','weinan','baoji')) then
list$#      insert into customer_sx values (new.*);
list$#   else
list$#      RAISE EXCEPTION 'City out of list.  Fix the customer_insert_trigger() function!';
list$#   end if;
list$#   return null;
list$# end;
list$# $$
list-# language plpgsql;
CREATE FUNCTION

创建触发器:

list=# CREATE TRIGGER insert_customer_trigger
list-#   BEFORE INSERT ON customer
list-#   FOR EACH ROW EXECUTE PROCEDURE customer_insert_trigger();
CREATE TRIGGER

查看主表结构:

list=# \d+ customer
                              Table "public.customer"
 Column |         Type          | Modifiers | Storage  | Stats target | Description 
--------+-----------------------+-----------+----------+--------------+-------------
 id     | integer               |           | plain    |              | 
 name   | character varying(20) |           | extended |              | 
 city   | character varying(30) |           | extended |              | 
Triggers:
    insert_customer_trigger BEFORE INSERT ON customer FOR EACH ROW EXECUTE PROCEDURE customer_insert_trigger()
Child tables: customer_sd,
              customer_sx
Has OIDs: no

插入测试数据:

list=# insert into customer values (1,'lian1','xian');
INSERT 0 0
list=# insert into customer values (2,'lian2','qingdao');
INSERT 0 0
list=# insert into customer values (3,'lian3','jinan');
INSERT 0 0
list=# insert into customer values (4,'lian4','weinan');
INSERT 0 0
list=# insert into customer values (5,'lian5','xianyang');
INSERT 0 0
list=# insert into customer values (6,'lian6','beijing');
ERROR:  City out of list.  Fix the customer_insert_trigger() function!

查看数据在分区上的分布:

list=# SELECT p.relname,c.*  FROM customer c, pg_class p WHERE c.tableoid = p.oid;
   relname   | id | name  |   city   
-------------+----+-------+----------
 customer_sd |  2 | lian2 | qingdao
 customer_sd |  3 | lian3 | jinan
 customer_sx |  1 | lian1 | xian
 customer_sx |  4 | lian4 | weinan
 customer_sx |  5 | lian5 | xianyang
(5 rows)

2.3 分区管理

2.3.1 删除分区

直接删除:

part=# drop table people_y2013m12;
DROP TABLE
part=# select * from people;
 id | name  |  logdate   
----+-------+------------
  2 | lian2 | 2014-01-10
  3 | lian3 | 2014-02-10
(2 rows)

part=# \d+ people
                                Table "public.people"
 Column  |         Type          | Modifiers | Storage  | Stats target | Description 
---------+-----------------------+-----------+----------+--------------+-------------
 id      | integer               | not null  | plain    |              | 
 name    | character varying(20) | not null  | extended |              | 
 logdate | date                  | not null  | plain    |              | 
Triggers:
    insert_people_trigger BEFORE INSERT ON people FOR EACH ROW EXECUTE PROCEDURE people_insert_trigger()
Child tables: people_y2014m01,
              people_y2014m02
Has OIDs: no

或不删除分区而是仅取消继承关系:

part=# alter table people_y2014m02 no inherit people;
ALTER TABLE
{将成为一个普通表存在,数据依然存在}
part=# select * from people_y2014m02;
 id | name  |  logdate   
----+-------+------------
  3 | lian3 | 2014-02-10
(1 row)
part=# \d+ people
                                Table "public.people"
 Column  |         Type          | Modifiers | Storage  | Stats target | Description 
---------+-----------------------+-----------+----------+--------------+-------------
 id      | integer               | not null  | plain    |              | 
 name    | character varying(20) | not null  | extended |              | 
 logdate | date                  | not null  | plain    |              | 
Triggers:
    insert_people_trigger BEFORE INSERT ON people FOR EACH ROW EXECUTE PROCEDURE people_insert_trigger()
Child tables: people_y2014m01
Has OIDs: no

取消继承关系的分区同样可以恢复继承关系(或清空数据后再重新继承):

part=# alter table people_y2014m02 inherit people;
ALTER TABLE
part=# \d+ people
                                Table "public.people"
 Column  |         Type          | Modifiers | Storage  | Stats target | Description 
---------+-----------------------+-----------+----------+--------------+-------------
 id      | integer               | not null  | plain    |              | 
 name    | character varying(20) | not null  | extended |              | 
 logdate | date                  | not null  | plain    |              | 
Triggers:
    insert_people_trigger BEFORE INSERT ON people FOR EACH ROW EXECUTE PROCEDURE people_insert_trigger()
Child tables: people_y2014m01,
              people_y2014m02
Has OIDs: no
part=# select * from people;
 id | name  |  logdate   
----+-------+------------
  2 | lian2 | 2014-01-10
  3 | lian3 | 2014-02-10
(2 rows)

2.3.2 添加分区

为people重新添加分区people_y2013m12:

part=# create table people_y2013m12( check( logdate >= DATE '2013-12-01' AND logdate < DATE '2014-01-01' ) ) inherits(people);
CREATE TABLE
part=# create index people_y2013m12_logdate on people_y2013m12(logdate);
CREATE INDEX
part=# \d+ people
                                Table "public.people"
 Column  |         Type          | Modifiers | Storage  | Stats target | Description 
---------+-----------------------+-----------+----------+--------------+-------------
 id      | integer               | not null  | plain    |              | 
 name    | character varying(20) | not null  | extended |              | 
 logdate | date                  | not null  | plain    |              | 
Triggers:
    insert_people_trigger BEFORE INSERT ON people FOR EACH ROW EXECUTE PROCEDURE people_insert_trigger()
Child tables: people_y2013m12,
              people_y2014m01,
              people_y2014m02
Has OIDs: no
{people_y2013m12已加入进继承关系中}

注意:若添加一个在触发器函数中未定义过范围的新分区则需要同时修改触发器函数。

建议:一般创建触发器函数时一个好习惯是将条件写得更未来一些(如多写一年或几年的时间),这样可以避免以后在需要创建新分区的时候需要重新创建触发器函数。

另一种添加新分区的方式

{创建一个与主表类似的表 → 为新表增加约束 → 建立继承关系}

语法如下:

create table t_name (like parent_name including defaults including constraints);
alter table t_name add constraint constr_name check ( logdate >= DATE '……' AND logdate < DATE '……' );
alter table t_name inherit parent_name;

2.3.3 分区表查询优化

通过调整数据库系统参数constraint_exclusion,控制是否检查表约束达到优化查询的效果。

constraint_exclusion = on/off/partition

on:检查所有表中的约束来优化查询

off:不检查表中的约束

partition:只检查继承子表和UNION ALL子句中涉及的约束(默认)

partition(默认):

part=# show constraint_exclusion ;
 constraint_exclusion 
----------------------
 partition
(1 row)
part=# explain select * from people where logdate >= '2014-01-01';
                                          QUERY PLAN                                          
----------------------------------------------------------------------------------------------
 Append  (cost=0.00..39.76 rows=567 width=66)
   ->  Seq Scan on people  (cost=0.00..0.00 rows=1 width=66)
         Filter: (logdate >= '2014-01-01'::date)
   ->  Bitmap Heap Scan on people_y2014m01  (cost=6.34..19.88 rows=283 width=66)
         Recheck Cond: (logdate >= '2014-01-01'::date)
         ->  Bitmap Index Scan on people_y2014m01_logdate  (cost=0.00..6.27 rows=283 width=0)
               Index Cond: (logdate >= '2014-01-01'::date)
   ->  Bitmap Heap Scan on people_y2014m02  (cost=6.34..19.88 rows=283 width=66)
         Recheck Cond: (logdate >= '2014-01-01'::date)
         ->  Bitmap Index Scan on people_y2014m02_logdate  (cost=0.00..6.27 rows=283 width=0)
               Index Cond: (logdate >= '2014-01-01'::date)
(11 rows)

{只扫描符合条件的分区}

on:

part=# set constraint_exclusion = on;
SET
part=# explain select * from people where logdate >= '2014-01-01';
                                          QUERY PLAN                                          
----------------------------------------------------------------------------------------------
 Append  (cost=0.00..39.76 rows=567 width=66)
   ->  Seq Scan on people  (cost=0.00..0.00 rows=1 width=66)
         Filter: (logdate >= '2014-01-01'::date)
   ->  Bitmap Heap Scan on people_y2014m01  (cost=6.34..19.88 rows=283 width=66)
         Recheck Cond: (logdate >= '2014-01-01'::date)
         ->  Bitmap Index Scan on people_y2014m01_logdate  (cost=0.00..6.27 rows=283 width=0)
               Index Cond: (logdate >= '2014-01-01'::date)
   ->  Bitmap Heap Scan on people_y2014m02  (cost=6.34..19.88 rows=283 width=66)
         Recheck Cond: (logdate >= '2014-01-01'::date)
         ->  Bitmap Index Scan on people_y2014m02_logdate  (cost=0.00..6.27 rows=283 width=0)
               Index Cond: (logdate >= '2014-01-01'::date)
(11 rows)

{只扫描符合条件的分区}

off:

part=# set constraint_exclusion = off;
SET
part=# explain select * from people where logdate >= '2014-01-01';
                                          QUERY PLAN                                          
----------------------------------------------------------------------------------------------
 Append  (cost=0.00..59.64 rows=850 width=66)
   ->  Seq Scan on people  (cost=0.00..0.00 rows=1 width=66)
         Filter: (logdate >= '2014-01-01'::date)
   ->  Bitmap Heap Scan on people_y2014m01  (cost=6.34..19.88 rows=283 width=66)
         Recheck Cond: (logdate >= '2014-01-01'::date)
         ->  Bitmap Index Scan on people_y2014m01_logdate  (cost=0.00..6.27 rows=283 width=0)
               Index Cond: (logdate >= '2014-01-01'::date)
   ->  Bitmap Heap Scan on people_y2014m02  (cost=6.34..19.88 rows=283 width=66)
         Recheck Cond: (logdate >= '2014-01-01'::date)
         ->  Bitmap Index Scan on people_y2014m02_logdate  (cost=0.00..6.27 rows=283 width=0)
               Index Cond: (logdate >= '2014-01-01'::date)
   ->  Bitmap Heap Scan on people_y2013m12  (cost=6.34..19.88 rows=283 width=66)
         Recheck Cond: (logdate >= '2014-01-01'::date)
         ->  Bitmap Index Scan on people_y2013m12_logdate  (cost=0.00..6.27 rows=283 width=0)
               Index Cond: (logdate >= '2014-01-01'::date)
(15 rows)

{对所有分区进行扫描}

2.4 通过rule重定向实现分区规则

实现分区规则不一定要用触发器,也可通过rule的方式来实现。

创建主表:

rule=# create table people(id int not null,name varchar(20) not null,logdate date not null);
CREATE TABLE

创建分区表:

rule=# create table people_y2013m12( check( logdate >= DATE '2013-12-01' AND logdate < DATE '2014-01-01' ) ) inherits(people);
CREATE TABLE
rule=# create table people_y2014m01( check( logdate >= DATE '2014-01-01' AND logdate < DATE '2014-02-01' ) ) inherits(people);
CREATE TABLE
rule=# create table people_y2014m02( check( logdate >= DATE '2014-02-01' AND logdate < DATE '2014-03-01' ) ) inherits(people);
CREATE TABLE

在主表上创建规则:

rule=# create rule people_insert_y2013m12 as
rule-# on insert to people where
rule-#   (logdate >= DATE '2013-12-01' AND logdate < DATE '2014-01-01')
rule-# do instead
rule-#   insert into people_y2013m12 values (new.*);
CREATE RULE
rule=# create rule people_insert_y2014m01 as
rule-#  on insert to people where
rule-#    (logdate >= DATE '2014-01-01' AND logdate < DATE '2014-02-01')
rule-#  do instead
rule-#    insert into people_y2014m01 values (new.*);
CREATE RULE
rule=# create rule people_insert_y2014m02 as
rule-#  on insert to people where
rule-#    (logdate >= DATE '2014-02-01' AND logdate < DATE '2014-03-01')
rule-#  do instead
rule-#    insert into people_y2014m02 values (new.*);
CREATE RULE

查看主表信息:

rule=# \d+ people
                                Table "public.people"
 Column  |         Type          | Modifiers | Storage  | Stats target | Description 
---------+-----------------------+-----------+----------+--------------+-------------
 id      | integer               | not null  | plain    |              | 
 name    | character varying(20) | not null  | extended |              | 
 logdate | date                  | not null  | plain    |              | 
Rules:
    people_insert_y2013m12 AS
    ON INSERT TO people
   WHERE new.logdate >= '2013-12-01'::date AND new.logdate < '2014-01-01'::date DO INSTEAD  INSERT INTO people_y2013m12 (id, name, logdate)
  VALUES (new.id, new.name, new.logdate)
    people_insert_y2014m01 AS
    ON INSERT TO people
   WHERE new.logdate >= '2014-01-01'::date AND new.logdate < '2014-02-01'::date DO INSTEAD  INSERT INTO people_y2014m01 (id, name, logdate)
  VALUES (new.id, new.name, new.logdate)
    people_insert_y2014m02 AS
    ON INSERT TO people
   WHERE new.logdate >= '2014-02-01'::date AND new.logdate < '2014-03-01'::date DO INSTEAD  INSERT INTO people_y2014m02 (id, name, logdate)
  VALUES (new.id, new.name, new.logdate)
Child tables: people_y2013m12,
              people_y2014m01,
              people_y2014m02
Has OIDs: no

插入测试数据:

rule=# insert into people values (1,'lian1','2013-12-05');
INSERT 0 0
rule=# insert into people values (2,'lian2','2014-01-05');
INSERT 0 0
rule=# insert into people values (3,'lian3','2014-02-05');
INSERT 0 0
rule=# insert into people values (4,'lian4','2014-03-05');
INSERT 0 1
rule=# SELECT p.relname,c.*  FROM people c, pg_class p WHERE c.tableoid = p.oid;
     relname     | id | name  |  logdate   
-----------------+----+-------+------------
 people          |  4 | lian4 | 2014-03-05
 people_y2013m12 |  1 | lian1 | 2013-12-05
 people_y2014m01 |  2 | lian2 | 2014-01-05
 people_y2014m02 |  3 | lian3 | 2014-02-05
(4 rows)
{不符合条件的数据被插入到了主表中}

rule方式的优缺点:

  • 批量插入(非copy)时,rule方式比trigger方式效率高。因为rule方式的额外开销是基于表而非基于行;

  • copy会忽略rule。若要使用copy插入数据并且分区是通过rule方式实现,则需要直接copy到对应的分区表中。而trigger方式则不存在这样的问题;

  • rule方式中不在定义范围内的插入不会报错,而是直接将数据插入到主表中。

2.5 注意事项

分区表

  • 由于在创建分区时系统不会自动检查分区条件的冲突性,因此在创建时需要格外注意创建代码的安全;

  • 在对表进行update的时候,不能对分区键值进行跨区更新,因为每个分区表上都有check约束,如下:

    a=# SELECT p.relname,c.*  FROM t c, pg_class p WHERE c.tableoid = p.oid;   relname   | id |  logdate    ------------+----+------------  t_y2014m01 |  1 | 2014-01-10  t_y2014m02 |  2 | 2014-02-10 (2 rows) a=# update t set logdate='2014-02-05' where logdate='2014-01-10'; ERROR:  new row for relation "t_y2014m01" violates check constraint "t_y2014m01_logdate_check" DETAIL:  Failing row contains (1, 2014-02-05). STATEMENT:  update t set logdate='2014-02-05' where logdate='2014-01-10'; ERROR:  new row for relation "t_y2014m01" violates check constraint "t_y2014m01_logdate_check" DETAIL:  Failing row contains (1, 2014-02-05). a=# update t set logdate='2014-01-05' where logdate='2014-01-10'; UPDATE 1 a=# SELECT p.relname,c.*  FROM t c, pg_class p WHERE c.tableoid = p.oid;   relname   | id |  logdate    ------------+----+------------  t_y2014m01 |  1 | 2014-01-05  t_y2014m02 |  2 | 2014-02-10 (2 rows) a=# update t set logdate='2014-01-05' where logdate='2014-01-10'; UPDATE 1 a=# SELECT p.relname,c.*  FROM t c, pg_class p WHERE c.tableoid = p.oid;   relname   | id |  logdate    ------------+----+------------  t_y2014m01 |  1 | 2014-01-05  t_y2014m02 |  2 | 2014-02-10 (2 rows) a=# update t_y2014m01 set logdate='2014-02-05' where logdate='2014-01-05'; ERROR:  new row for relation "t_y2014m01" violates check constraint "t_y2014m01_logdate_check" DETAIL:  Failing row contains (1, 2014-02-05). STATEMENT:  update t_y2014m01 set logdate='2014-02-05' where logdate='2014-01-05'; ERROR:  new row for relation "t_y2014m01" violates check constraint "t_y2014m01_logdate_check" DETAIL:  Failing row contains (1, 2014-02-05).

  • 在对表进行VACUUM或ANALYZE操作时,需要在每一个分区表上操作,并非直接对主表操作即可。

约束排除

  • 只当查询的where子句中包含约束时有效;

  • CHECK中应避免跨数据类型的比较,因为规划器无法做出正确的判断;

  • 由于规划器会对主表的所有分区表上的约束都会进行一次检查,所以过多的分区会需要大量的约束排除检查时间,因此要避免在分区多达成百上千的情况下使用。

PostgreSQL从继承到分区(一)

http://my.oschina.net/lianshunke/blog/205296

PostgreSQL从继承到分区(二)

http://my.oschina.net/lianshunke/blog/205296

PostgreSQL从继承到分区(三)

http://my.oschina.net/lianshunke/blog/205316

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这