头像

[postgresql] – 重复数据删除,仅保留其中一条

1.常规删除方法
explain analyse delete from deltest a where a.ctid <> (select min(t.ctid) from deltest t where a.id=t.id);
2.group by删除方法
explain analyse delete from deltest a where a.ctid not in (select min(ctid) from deltest group by id);
3.row_number删除方法
explain analyze delete from deltest a where a.ctid = any(array (select ctid from (select row_number() over (partition by id), ctid from deltest) t where t.row_number > 1));

根据某个字段分组删除重复数据,只保留日期最大的一条,建议使用窗口函数效率更高

头像

Postgres数据库忘记密码,只需三个步骤重置

Postgres数据库忘记密码,三个步骤解决
一、修改data目录下的 pg_hba.conf 文件
将以下这行
host    all            all           127.0.0.1/32          md5
改为如下:
host    all            all           127.0.0.1/32          trust
如果开启ipv6的话,以下也要修改
# IPv6 local connections:
host all all ::1/128 trust
二、运行cmd,进入postgres安装路径的bin目录,运行如下命令:
psql -U postgres
postgres=# alter user postgres with password ‘你要设置的密码';
postgres=# \q 
三、修改data目录下的 pg_hba.conf 文件
将以下这行

host  all   all  127.0.0.1/32  trust
改为如下:
host  all   all  127.0.0.1/32  md5
ipv6的密码方式也修改
重新启动postgres
头像

pg_restore数据库恢复指令

pg_restore restores a PostgreSQL database from an archive created by pg_dump.

Usage:
pg_restore [OPTION]… [FILE]

General options:
-d, –dbname=NAME        connect to database name
-f, –file=FILENAME      output file name
-F, –format=c|d|t       backup file format (should be automatic)
-l, –list               print summarized TOC of the archive
-v, –verbose            verbose mode
–help                   show this help, then exit
–version                output version information, then exit

Options controlling the restore:
-a, –data-only          restore only the data, no schema
-c, –clean              clean (drop) database objects before recreating
-C, –create             create the target database
-e, –exit-on-error      exit on error, default is to continue
-I, –index=NAME         restore named index
-j, –jobs=NUM           use this many parallel jobs to restore
-L, –use-list=FILENAME  use table of contents from this file for
selecting/ordering output
-n, –schema=NAME        restore only objects in this schema
-O, –no-owner           skip restoration of object ownership
-P, –function=NAME(args)
restore named function
-s, –schema-only        restore only the schema, no data
-S, –superuser=NAME     superuser user name to use for disabling triggers
-t, –table=NAME         restore named table
-T, –trigger=NAME       restore named trigger
-x, –no-privileges      skip restoration of access privileges (grant/revoke)
-1, –single-transaction
restore as a single transaction
–disable-triggers       disable triggers during data-only restore
–no-data-for-failed-tables
do not restore data of tables that could not be
created
–no-security-labels     do not restore security labels
–no-tablespaces         do not restore tablespace assignments
–use-set-session-authorization
use SET SESSION AUTHORIZATION commands instead of
ALTER OWNER commands to set ownership

Connection options:
-h, –host=HOSTNAME      database server host or socket directory
-p, –port=PORT          database server port number
-U, –username=NAME      connect as specified database user
-w, –no-password        never prompt for password
-W, –password           force password prompt (should happen automatically)
–role=ROLENAME          do SET ROLE before restore

If no input file name is supplied, then standard input is used.

头像

PostgreSQL11允许远程访问

安装目录PostgreSQL\11\data\pg_hba.conf

# IPv4 local connections:
host    all             all             127.0.0.1/32            md5
host    all             all             192.168.1.0/24            md5

表示允许网段192.168.1.0上的所有主机访问数据库。

0.0.0.0/0,表示允许所有主机访问数据库。

其中,数字24是子网掩码,表示允许192.168.1.0–192.168.1.255的计算机访问。

头像

帝国备份王备份、恢复数据库时页面空白

备份:

最近有个数据库需要备份,就想到了用帝国备份王备份,但是我配置好数据库后,点击备份数据库,点开始备份以后也空白。
后来查阅了相关资料,发现,如果你数据库有数字开头的数据表的情况下,还有数据表使用了保留关键字作为表名都会出现页面空白的问题。

我看了下自己数据库只有一个带数字的表。果断跳过,不备份这个表,即可。

还原:

因为数据文件比较大,超100M了,所以用帝国备份王恢复数据。但每次恢复着就突然白屏了,后来经检查发现,原来我的备份的文件有几个文件Ftp没上传成功,在服务器上显示0kb,后来重新上传就可以了,如果出现类似情况,可以用我这个方法检查一下。

头像

MAMP pro mysql 启动失败

网上有很多关于Mac os 安装MAMP PRO后出现数据库无法启动的故障处理办法,然而每个都试了,完全不能解决问题,错误提示是:

InnoDB: The error means the system cannot find the path specified.

InnoDB: If you are installing InnoDB, remember that you must create

InnoDB: directories yourself, InnoDB does not create them.

InnoDB: Error: could not open single-table tablespace file ./mysql/slave_relay_log_info.ibd

InnoDB: We do not continue the crash recovery, because the table may become

InnoDB: corrupt if we cannot apply the log records in the InnoDB log to it.

InnoDB: To fix the problem and start mysqld:

InnoDB: 1) If there is a permission problem in the file and mysqld cannot

InnoDB: open the file, you should modify the permissions.

InnoDB: 2) If the table is not needed, or you can restore it from a backup,

InnoDB: then you can remove the .ibd file, and InnoDB will do a normal

InnoDB: crash recovery and ignore that table.

InnoDB: 3) If the file system or the disk is broken, and you cannot remove

InnoDB: the .ibd file, you can set innodb_force_recovery > 0 in my.cnf

InnoDB: and force InnoDB to continue crash recovery here.

170324 11:18:41 mysqld_safe mysqld from pid file /Applications/MAMP/tmp/mysql/mysql.pid ended

出现这个情况是之前已经安装过MAMP PRO,从倒数第三行的提示来看需要修改my.cnf,使用mamp打开mysql是可以正常启动的,但是Hosts无法修改路径及配置多个测试域名,每次都要去修改一大堆东西,很不方便,下面我们来解决MAMP PRO mysql无法启动的问题;

其实原因初步判断应该是在MAMP PRO的应用管理端,从应用程序管理文件夹,找到MAMP PRO,显示包内容,完成访问路径/Applications/MAMP PRO/MAMP PRO.app/Contents/Resources/my.cnf,复制你对应版本的my.cnf文件到桌面,修改innodb force recovery=2;将原来的备份,替换对应版本的my.cnf,修改完成回到MAMP PRO控制面板,点击mysql,成功启动!

因为我的是多版本,所以打开的是my56.cnf

mamp-sql1
最后来张成功启动的截图,有图有真相

mamp-sql2

作者:cabin_ysl
链接:https://www.jianshu.com/p/4f6644c644ba
来源:简书

头像

SQL SERVER函数之 计算地球上两个坐标点距离

SQL函数

GO
–计算地球上两个坐标点(经度,纬度)之间距离sql函数
CREATE FUNCTION [dbo].[GetDistance](@LatBegin REAL, @LngBegin REAL, @LatEnd REAL, @LngEnd REAL) RETURNS FLOAT
AS
BEGIN
–距离(米)
DECLARE @Distance REAL
DECLARE @EARTH_RADIUS REAL
SET @EARTH_RADIUS = 6371393
DECLARE @RadLatBegin REAL,@RadLatEnd REAL,@RadLatDiff REAL,@RadLngDiff REAL
SET @RadLatBegin = @LatBegin *PI()/180.0
SET @RadLatEnd = @LatEnd *PI()/180.0
SET @RadLatDiff = @RadLatBegin – @RadLatEnd
SET @RadLngDiff = @LngBegin *PI()/180.0 – @LngEnd *PI()/180.0
SET @Distance = 2 *ASIN(SQRT(POWER(SIN(@RadLatDiff/2), 2)+COS(@RadLatBegin)*COS(@RadLatEnd)*POWER(SIN(@RadLngDiff/2), 2)))
SET @Distance = @Distance * @EARTH_RADIUS
RETURN @Distance
END

 
SQL 自带数据类型 GEOGRAPHY ,函数 : STDistance

GO
–计算地球上两个坐标点(经度,纬度)之间距离sql函数
CREATE FUNCTION [dbo].[GetDistanceByNative](@LatBegin REAL, @LngBegin REAL, @LatEnd REAL, @LngEnd REAL) RETURNS FLOAT
AS
BEGIN
–距离(米)
DECLARE @Distance REAL
Set @Distance=geography::Point(@LatBegin, @LngBegin, 4326).STDistance(geography::Point(@LatEnd,@LngEnd, 4326))
RETURN @Distance
END

头像

MySQL分区总结

MySQL支持RANGE,LIST,HASH和KEY四种分区。其中,每个分区又都有一种特殊的类型。对于RANGE分区,有RANGE COLUMNS分区。对于LIST分区,有LIST COLUMNS分区。对于HASH分区,有LINEAR HASH分区。对于KEY分区,有LINEAR KEY分区。具体如下:

 

RANGE分区

RANGE即范围分区,根据区间来判断位于哪个分区,譬如,在下例中,如果store_id小于6,则新增或修改的记录会被分配到p0分区,如果大于6小于11,则记录会被分配到p1分区,依次类推。类似于编程语言中的if … elseif …语句。

格式如下:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN MAXVALUE
);

注意:

1. RANGE分区的返回值必须为整数。

2. PARTITION p3 VALUES LESS THAN MAXVALUE 是非必需的。

 

RANGE COLUMNS分区

RANGE COLUMNS是RANGE分区的一种特殊类型,它与RANGE分区的区别如下:

1. RANGE COLUMNS不接受表达式,只能是列名。而RANGE分区则要求分区的对象是整数。

2. RANGE COLUMNS允许多个列,在底层实现上,它比较的是元祖(多个列值组成的列表),而RANGE比较的是标量,即数值的大小。

3. RANGE COLUMNS不限于整数对象,date,datetime,string都可作为分区列。

格式如下:

CREATE TABLE rcx (
    a INT,
    b INT,
    c CHAR(3),
    d INT
)
PARTITION BY RANGE COLUMNS(a,d,c) (
    PARTITION p0 VALUES LESS THAN (5,10,'ggg'),
    PARTITION p1 VALUES LESS THAN (10,20,'mmmm'),
    PARTITION p2 VALUES LESS THAN (15,30,'sss'),
    PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE,MAXVALUE)
);

同RANGE分区类似,它的区间范围必须是递增的,有时候,列涉及的太多,不好判断区间的大小,可采用下面的方式进行判断:

mysql> SELECT (5,10) < (5,12), (5,11) < (5,12), (5,12) < (5,12);
+-----------------+-----------------+-----------------+
| (5,10) < (5,12) | (5,11) < (5,12) | (5,12) < (5,12) |
+-----------------+-----------------+-----------------+
|               1 |               1 |               0 |
+-----------------+-----------------+-----------------+
1 row in set (0.07 sec)

关于RANGE COLUMNS的更多说明,可参考MySQL官方文档:

http://dev.mysql.com/doc/refman/5.6/en/partitioning-columns-range.html

 

LIST分区

LIST即列表分区。

格式如下:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LIST(store_id) (
    PARTITION pNorth VALUES IN (3,5,6,9,17),
    PARTITION pEast VALUES IN (1,2,10,11,19,20),
    PARTITION pWest VALUES IN (4,12,13,14,18),
    PARTITION pCentral VALUES IN (7,8,15,16)
);

 

LIST COLUMNS分区

LIST COLUMNS分区同样是LIST分区的一种特殊类型,它和RANGE COLUMNS分区较为相似,同样不接受表达式,同样支持多个列支持string,date和datetime类型。

格式如下:

CREATE TABLE customers_1 (
    first_name VARCHAR(25),
    last_name VARCHAR(25),
    street_1 VARCHAR(30),
    street_2 VARCHAR(30),
    city VARCHAR(15),
    renewal DATE
)
PARTITION BY LIST COLUMNS(renewal) (
    PARTITION pWeek_1 VALUES IN('2010-02-01', '2010-02-02', '2010-02-03',
        '2010-02-04', '2010-02-05', '2010-02-06', '2010-02-07'),
    PARTITION pWeek_2 VALUES IN('2010-02-08', '2010-02-09', '2010-02-10',
        '2010-02-11', '2010-02-12', '2010-02-13', '2010-02-14'),
    PARTITION pWeek_3 VALUES IN('2010-02-15', '2010-02-16', '2010-02-17',
        '2010-02-18', '2010-02-19', '2010-02-20', '2010-02-21'),
    PARTITION pWeek_4 VALUES IN('2010-02-22', '2010-02-23', '2010-02-24',
        '2010-02-25', '2010-02-26', '2010-02-27', '2010-02-28')
);

多列格式如下:

CREATE TABLE customers_2 (
    first_name VARCHAR(25),
    last_name VARCHAR(25),
    street_1 VARCHAR(30),
    street_2 VARCHAR(30),
    city VARCHAR(15),
    renewal DATE
)
PARTITION BY LIST COLUMNS(city,last_name,first_name) (
    PARTITION pRegion_1 VALUES IN (('Oskarshamn', 'Högsby', 'Mönsterås'),('Nässjö', 'Eksjö', 'Vetlanda')),
    PARTITION pRegion_2 VALUES IN(('Vimmerby', 'Hultsfred', 'Västervik'),('Uppvidinge', 'Alvesta', 'Växjo'))
);

 

HASH分区

和RANGE,LIST分区不同的是,HASH分区无需定义分区的条件。只需要指明分区数即可。

格式如下:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;

注意:

1. HASH分区可以不用指定PARTITIONS子句,如上文中的PARTITIONS 4,则默认分区数为4。

2. 不允许只写PARTITIONS,而不指定分区数。

3. 同RANGE分区和LIST分区一样,PARTITION BY HASH (expr)子句中的expr返回的必须是整数值。

4. HASH分区的底层实现其实是基于MOD函数。譬如,对于下表

CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATE)
    PARTITION BY HASH( YEAR(col3) )
    PARTITIONS 4;

如果你要插入一个col3为“2005-09-15”的记录,则分区的选择是根据以下值决定的:

MOD(YEAR('2005-09-01'),4)
=  MOD(2005,4)
=  1

 

LINEAR HASH分区

LINEAR HASH分区是HASH分区的一种特殊类型,与HASH分区是基于MOD函数不同的是,它基于的是另外一种算法。

格式如下:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LINEAR HASH( YEAR(hired) )
PARTITIONS 4;

说明:

1. 它的优点是在数据量大的场景,譬如TB级,增加、删除、合并和拆分分区会更快,缺点是,相对于HASH分区,它数据分布不均匀的概率更大。

2. 具体算法,可参考MySQL的官方文档

http://dev.mysql.com/doc/refman/5.6/en/partitioning-linear-hash.html

 

KEY分区

KEY分区其实跟HASH分区差不多,不同点如下:

1. KEY分区允许多列,而HASH分区只允许一列。

2. 如果在有主键或者唯一键的情况下,key中分区列可不指定,默认为主键或者唯一键,如果没有,则必须显性指定列。

3. KEY分区对象必须为列,而不能是基于列的表达式。

4. KEY分区和HASH分区的算法不一样,PARTITION BY HASH (expr),MOD取值的对象是expr返回的值,而PARTITION BY KEY (column_list),基于的是列的MD5值。

格式如下:

CREATE TABLE k1 (
    id INT NOT NULL PRIMARY KEY,
    name VARCHAR(20)
)
PARTITION BY KEY()
PARTITIONS 2;

在没有主键或者唯一键的情况下,格式如下:

CREATE TABLE tm1 (
    s1 CHAR(32)
)
PARTITION BY KEY(s1)
PARTITIONS 10;

 

LINEAR KEY分区

LINEAR HASH分区类似。

格式如下:

CREATE TABLE tk (
    col1 INT NOT NULL,
    col2 CHAR(5),
    col3 DATE
)
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;

 

总结:

1. MySQL分区中如果存在主键或唯一键,则分区列必须包含在其中。

2. 对于原生的RANGE分区,LIST分区,HASH分区,分区对象返回的只能是整数值。

3. RANGE COLUMNS,LIST COLUMNS,KEY,LINEAR KEY分区对象只能是列,不能是基于列的表达式。

头像

mysql分表,分区的区别和联系

一,什么是mysql分表,分区

什么是分表,从表面意思上看呢,就是把一张表分成N多个小表,具体请看mysql分表的3种方法

什么是分区,分区呢就是把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,具体请参考mysql分区功能详细介绍,以及实例

二,mysql分表和分区有什么区别呢

1,实现方式上

a),mysql的分表是真正的分表,一张表分成很多表后,每一个小表都是完正的一张表,都对应三个文件,一个.MYD数据文件,.MYI索引文件,.frm表结构文件。

  1. [root@BlackGhost test]# ls |grep user
  2. alluser.MRG
  3. alluser.frm
  4. user1.MYD
  5. user1.MYI
  6. user1.frm
  7. user2.MYD
  8. user2.MYI
  9. user2.frm

简单说明一下,上面的分表呢是利用了merge存储引擎(分表的一种),alluser是总表,下面有二个分表,user1,user2。他们二个都是独立的表,取数据的时候,我们可以通过总表来取。这里总表是没有.MYD,.MYI这二个文件的,也就是说,总表他不是一张表,没有数据,数据都放在分表里面。我们来看看.MRG到底是什么东西

  1. [root@BlackGhost test]# cat alluser.MRG |more
  2. user1
  3. user2
  4. #INSERT_METHOD=LAST

从上面我们可以看出,alluser.MRG里面就存了一些分表的关系,以及插入数据的方式。可以把总表理解成一个外壳,或者是联接池。

b),分区不一样,一张大表进行分区后,他还是一张表,不会变成二张表,但是他存放数据的区块变多了。

  1. [root@BlackGhost test]# ls |grep aa
  2. aa#P#p1.MYD
  3. aa#P#p1.MYI
  4. aa#P#p3.MYD
  5. aa#P#p3.MYI
  6. aa.frm
  7. aa.par

从上面我们可以看出,aa这张表,分为二个区,p1和p3,本来是三个区,被我删了一个区。我们都知道一张表对应三个文件.MYD,.MYI,.frm。分区呢根据一定的规则把数据文件和索引文件进行了分割,还多出了一个.par文件,打开.par文件后你可以看出他记录了,这张表的分区信息,根分表中的.MRG有点像。分区后,还是一张,而不是多张表。

2,数据处理上

a),分表后,数据都是存放在分表里,总表只是一个外壳,存取数据发生在一个一个的分表里面。看下面的例子:

select * from alluser where id=’12’表面上看,是对表alluser进行操作的,其实不是的。是对alluser里面的分表进行了操作。

b),分区呢,不存在分表的概念,分区只不过把存放数据的文件分成了许多小块,分区后的表呢,还是一张表。数据处理还是由自己来完成。

3,提高性能上

a),分表后,单表的并发能力提高了,磁盘I/O性能也提高了。并发能力为什么提高了呢,因为查寻一次所花的时间变短了,如果出现高并发的话,总表可以根据不同的查询,将并发压力分到不同的小表里面。磁盘I/O性能怎么搞高了呢,本来一个非常大的.MYD文件现在也分摊到各个小表的.MYD中去了。

b),mysql提出了分区的概念,我觉得就想突破磁盘I/O瓶颈,想提高磁盘的读写能力,来增加mysql性能。
在这一点上,分区和分表的测重点不同,分表重点是存取数据时,如何提高mysql并发能力上;而分区呢,如何突破磁盘的读写能力,从而达到提高mysql性能的目的。

4),实现的难易度上

a),分表的方法有很多,用merge来分表,是最简单的一种方式。这种方式根分区难易度差不多,并且对程序代码来说可以做到透明的。如果是用其他分表方式就比分区麻烦了。

b),分区实现是比较简单的,建立分区表,根建平常的表没什么区别,并且对开代码端来说是透明的。

三,mysql分表和分区有什么联系呢

1,都能提高mysql的性高,在高并发状态下都有一个良好的表面。

2,分表和分区不矛盾,可以相互配合的,对于那些大访问量,并且表数据比较多的表,我们可以采取分表和分区结合的方式(如果merge这种分表方式,不能和分区配合的话,可以用其他的分表试),访问量不大,但是表数据很多的表,我们可以采取分区的方式等。


作者:海底苍鹰
转载地址:http://blog.51yip.com/mysql/1029.html