小编joa*_*olo的帖子

如何在减少膨胀或 ALTER (ing) 表的同时最小化访问独占表锁?

在某些情况下,我被告知不要对生产中的表执行 VACUUM FULL(或 CLUSTER),因为这将独占锁定它的时间比预期的要长。这同样适用于几个 ALTER TABLE 操作(例如更改几个列的类型)。

提出的替代方案始终是执行以下操作:

 CREATE TABLE new_table AS SELECT * FROM old_table ;
 -- recreate all indices and constraints
 ALTER TABLE old_table RENAME TO going_to_drop_table ;
 ALTER TABLE new_table RENAME TO old_table ;
 DROP TABLE going_to_drop_table ;
Run Code Online (Sandbox Code Playgroud)

这适用于没有依赖关系的场景old_table(意味着没有任何依赖它的视图,也没有任何外键约束、函数等),并且old_table没有任何插入或更新。但在大多数数据库中,这将是一个例外,而不是规则。

有没有办法在不丢失依赖关系的情况下进行这样的“表交换”?

[为了完整起见:我对如何为 PostgreSQL 9.5 或 9.6 做这件事特别感兴趣]


研究到现在(关于根本原因):

  1. 是否可以在 Postgres 中异步运行 VACUUM FULL?=> pg_repack。注意事项:在 Windows 上可能不容易实现,未使用 postgresql 9.6 进行测试。看起来是最有希望的选择。
  2. pg_reorg: 类似于 pg_repack(是它的基础)=> 自 postgresql 9.4 以来似乎没有更新,并且它主要被pg_repack.
  3. 来自 …

postgresql optimization maintenance online-operations postgresql-9.6

7
推荐指数
0
解决办法
690
查看次数

innodb 上大表的自动增量与复合主键

我和 Rick James 就这个问题进行了很长时间的讨论,我们提出了用复合键替换自动增量 pk 的想法,其中 int 限制接近 20 亿。我的表将在几个月内轻松达到此限制,因为我们每月捕获近几亿数据。下面是我的桌子的样子。关键表是gdata所以我使用 3 个字段组合主表PRIMARY KEY (alarmTypeID,vehicleID,gDateTime)。然后我有另一个表称为警报表。两者之间的联系是一对多的。这意味着其中的一个数据gdata可以有零个或多个alarms与之相关。它们之间的链接是vehicleIDgDateTime

CREATE TABLE `gdata` ( 
    `alarmTypeID` tinyint(4) NOT NULL DEFAULT '0', 
    `fleetID` smallint(11) NOT NULL, 
    `fleetGroupID` smallint(11) DEFAULT NULL, 
    `fleetSubGroupID` smallint(11) DEFAULT NULL, 
    `deviceID` mediumint(11) NOT NULL, 
    `vehicleID` mediumint(11) NOT NULL, 
    `gDateTime` datetime NOT NULL, 
    `insertDateTime` datetime NOT NULL, 
    `latitude` float NOT NULL, 
    `longitude` float NOT NULL, 
    `speed` smallint(11) NOT NULL
     -- (see full text) …
Run Code Online (Sandbox Code Playgroud)

mysql innodb index primary-key clustered-primary-key

7
推荐指数
1
解决办法
7682
查看次数

季度的通用结束日期,PostgreSQL

我想生成给定日期的通用季度结束日期。

例如:如果我有2010-01-01,我想返回2010-03-31,等等。

我可以得到季度号和年份:

select to_char(date_trunc('quarter',  current_date)::date, 'yyyy-q');
Run Code Online (Sandbox Code Playgroud)

2017-3从今天起返回的是2017-07-14

我如何很好地获得季度结束日期?

我可以得到答案,但它非常丑陋:

select to_char(date_trunc('year',  date '2015-01-01'),'yyyy') || '-' ||case
    when (select extract('quarter' from date_trunc('quarter', date '2015-01-01')::date )) = 1 then '03-31'
    when (select extract('quarter' from date_trunc('quarter', date '2015-01-01')::date )) = 2 then '06-30'
    when (select extract('quarter' from date_trunc('quarter', date '2015-01-01')::date )) = 3 then '09-30'
    when (select extract('quarter' from date_trunc('quarter', date '2015-01-01')::date )) = 4 then '12-31'
    else '?'
    end 
Run Code Online (Sandbox Code Playgroud)

返回2015-03-31因为我把2015-01-01

有没有更好的办法?

postgresql functions date interval

7
推荐指数
1
解决办法
8356
查看次数

一对“零或一”关系

我有以下要求:

  • 每笔交易都有以下类型之一;借记、贷记、存款或取款。

  • 借方或贷方交易必须有链接的发票记录,并且没有银行账户记录。

  • 存款或取款交易必须有关联的银行账户记录且无发票记录。


目前我的基本设计是这样的:

粗略的数据库设计

我目前的解决方案是:

  1. 一种交易表中发票和银行账户表的两个可为空的外键。但是,我认为可空的外键列不是一个好的设计。
  2. 在链接到交易表的发票和银行账户表中有一个外键。然而,它似乎更难查询,并且它模拟了一对多关系(不是我想要的一对一可选关系)。

我概述的哪种方法是更好的解决方案?或者还有其他更好的方法来满足我的约束吗?

mysql database-design subtypes

6
推荐指数
1
解决办法
3772
查看次数

在 ORDER BY 中使用 CASE .. END 有意义吗?

类似SELECT * FROM t ORDER BY case when _parameter='a' then column_a end, case when _parameter='b' then column_b end的查询是可能的,但是:这是一个好习惯吗?

在查询的 WHERE 部分使用参数是很常见的,在 SELECT 部分有一些计算列,但参数化 ORDER BY 子句并不常见。

假设我们有一个列出二手车的应用程序 (à la CraigsList)。汽车列表可以按价格或颜色排序。我们有一个函数,给定一定数量的参数(比如价格范围、颜色和排序标准),它会返回一组带有结果的记录。

为了具体起见,让我们假设cars都在下表中:

CREATE TABLE cars
(
  car_id serial NOT NULL PRIMARY KEY,  /* arbitrary anonymous key */
  make text NOT NULL,       /* unnormalized, for the sake of simplicity */
  model text NOT NULL,      /* unnormalized, for the sake of simplicity */
  year integer,             /* may …
Run Code Online (Sandbox Code Playgroud)

postgresql order-by dynamic-sql functions postgresql-9.6

6
推荐指数
1
解决办法
9741
查看次数

PostgreSQL - 设计数据库以避免频繁更新大型数据集

我们正在尝试使用这些数字和查询要求来优化数据库的性能:

  1. 200-400k 网段由唯一ID标识
  2. 每个网段都有一个状态,其动态属性数量有限(即平均速度)。动态属性的单个状态可以存储在 8 个字节中
  3. 段状态每 3 分钟改变一次,H24,7/7
  4. 是否可以查询特定日期范围内的一组段(有时是所有段)的状态或仅查询实际情况。
  5. 可以请求空间查询以查找特定日期(通常是“现在”)“我周围”的所有段

有了这些必要条件,我们就得出了这个解决方案(有一个很大的缺点,解释如下)。

[A] TABLE main_segments_history( 
      id_segment integer NOT NULL,
      day date NOT NULL,    
      day_slices bigint[],
      CONSTRAINT main_segments_history_pk PRIMARY KEY (id_segment,day)
)

[B] TABLE current_segment_release_state(
      id_segment integer NOT NULL,
      release_date timestamptz,
      ... all other attributes ...
      CONSTRAINT currsegm_release_state_pk PRIMARY KEY (id_segment,release_date)
)
Run Code Online (Sandbox Code Playgroud)

解释[A]表:

  1. 它在字段“day”上使用 partition_manager ( pg_partman)进行分区。每个分区是一个月
  2. day_slices 数组是一个 480 个元素的一维数组,表示全天每个 3 分钟切片的粒度

解释[B]表:

  1. 它只是每个段的当前发布状态

有一个后端进程详细说明了网络。
它每 3 分钟插入或更新每个段的状态。
换句话说,此过程将在一天开始时插入新行,并将每 3 分钟更新一次内部数组。

该解决方案的优点 …

postgresql performance database-design

6
推荐指数
1
解决办法
1287
查看次数

基于某个类别的前 n 个列的总和

我有以下输入,我需要计算每个类别前 x 周数的值的总和。

输入

如果 x 为 3,输出将如下所示:

在此处输入图片说明

请注意,最后一个值为 49,因为自 x=3 以来,它仅将上周的值添加到当前周。

我希望将 SQL 编写为存储过程,并且需要一些有关执行此操作的适当方法的帮助。

在@sp_BlitzErik 的帮助下,我尝试使用LAG,但无法完全到达我需要的地方。这是我的查询:

SELECT category
    ,year
    ,week
    ,value
    ,(
        LAG(value, 1, 0) OVER (
            ORDER BY category
                ,year
                ,week
            ) + LAG(value, 2, 0) OVER (
            ORDER BY category
                ,year
                ,week
            ) + value
        ) AS cumulative_value
FROM valuedata
Run Code Online (Sandbox Code Playgroud)

输出还不太正确:

在此处输入图片说明

sql-server aggregate t-sql window-functions

6
推荐指数
1
解决办法
4万
查看次数

REFERENCES 特权仅与创建外键约束有关?实际用例?

今天我了解了GRANT REFERENCES. 在多年的 SQL 管理和开发工作中,我从未听说过它,也从未遇到过问题。

引用自MySQL 5.7 参考手册/GRANT 语法

REFERENCES 启用外键创建。级别:全局、数据库、表、列。

引用自PostgreSQL 9.6 / GRANT

REFERENCES 要创建外键约束,必须对引用列和被引用列都具有此权限。可以为表的所有列或仅特定列授予特权。

GRANT REFERENCES唯一的有关创建一个外键约束?在什么业务案例中禁止创建外键约束(但允许创建表)有意义?你能给我举个真实世界的例子吗?

mysql postgresql foreign-key permissions referential-integrity

5
推荐指数
2
解决办法
6737
查看次数

如果在事务中间插入数据会发生什么?

我是数据库的新手,我对交易迷路了。例如,在我有一个sensor_log不断接收 INSERT的表的情况下,我想在一个事务中将数据移动到另外两个表。

BEGIN;

INSERT INTO sensor_log_a
SELECT id, location 
FROM sensor_log
INNER JOIN sensor_location_to_insert USING (location);

INSERT INTO sensor_log_b
SELECT id, location 
FROM sensor_log
INNER JOIN sensor_location_to_insert USING (location);

COMMIT;
Run Code Online (Sandbox Code Playgroud)

如果在事务期间插入数据或BEGIN;..COMMIT;防止这种情况发生,是否存在数据在 sensor_log_a 和 sensor_log_b 之间不同的风险?

postgresql

5
推荐指数
1
解决办法
1147
查看次数

客户端应用程序在 10 分钟不活动后与其连接的数据库断开连接

当使用 pgAdmin 4(实际上是其他几个充当数据库客户端的程序)时,与服务器的连接在闲置 10 或 15 分钟后断开。一杯咖啡和一个电话,您会收到一条类似于“抱歉,与数据库的连接已丢失。您希望我尝试重新连接吗?”的消息。

而且pgAdmin重新连接总是需要多次尝试,并且已经展开的对象树被折叠了......所以,这有点烦人。

pgAdmin 似乎没有与该行为相关的任何参数。(似乎有一些方法可以更改某些连接超时,但它们与 pgAdmin 在服务器连接时间过长时的行为方式有关)。

可以做些什么来避免 pgAdmin 与数据库断开连接?


披露:这实际上是一个“伪问题”。它是另一个的衍生产品,最终与失去连接无关......鉴于我已经有了一个答案,我(不是很谦虚地)认为值得“问”,以防万一回答对某人有帮助。

postgresql client pgadmin network connectivity

5
推荐指数
1
解决办法
2万
查看次数