相关疑难解决方法(0)

将常见查询存储为列?

使用PostgreSQL,我有很多查询,如下所示:

SELECT <col 1>, <col 2>
     , (SELECT sum(<col x>)
        FROM   <otherTable> 
        WHERE  <other table foreignkeyCol>=<this table keycol>) AS <col 3>
FROM   <tbl>
Run Code Online (Sandbox Code Playgroud)

鉴于子选择在每种情况下都是相同的,有没有办法将该子选择存储为表中的伪列?基本上,我希望能够从表A中选择一列,它是表B中与记录相关的特定列的总和.这可能吗?

postgresql database-design view

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

查询 json / jsonb 列超级慢。我可以使用索引吗?

我正在尝试加快对 PostgreSQL 数据库中存储的一些 json 数据的查询速度。我继承了一个应用程序,该应用程序查询一个名为 的 PostgreSQL 表,该data表带有一个名为 的字段value,其中值是类型为 json 的 blob jsonb

它大约有 300 行,但从 5 个 json 元素中选择此数据需要 12 秒。json blob 有点大,但我需要的数据都在 json 嵌套的顶层(如果有帮助的话)。

我尝试添加索引,CREATE INDEX idx_tbl_data ON data USING gin (value);但这没有帮助。我应该使用不同的索引吗?长期愿景是重写应用程序以将数据移出 json,但由于应用程序其他部分的复杂性,这至少需要 30-40 个工作日的工作,所以我想看看是否可以可以在短期内加快速度。

不确定它是否有帮助,但构成此结果集的基础数据不会经常更改。经常发生变化的是 json blob 中更下方的数据。

SELECT
  value::json ->> 'name' AS name,
  value::json ->> 'mnemonic' AS mnemonic,
  value::json ->> 'urlName' AS "urlName",
  value::json ->> 'countryCode' AS "countryCode",
  value::json #>>'{team}' AS team
FROM
  data;
Run Code Online (Sandbox Code Playgroud)

postgresql json postgresql-performance jsonb

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

PostgreSQL 在外键中使用常量

外键的语法,如官方文档中所述,包括表 A 中的列集引用表 B 中的列集。

是否可以在外键声明中使用常量?

问题是,我有表 DICTIONARIES,其中包含所有字典值,按类型区分。我知道这不是一个好的设计,但不幸的是,我没什么可说的,因为数据库管理员想要“最小化表的数量”......

是否有可能实现类似的目标:

CREATE TABLE PERSON (
  id integer primary key,
  country_id integer,
  ...
  FOREIGN KEY ('COUNTRY', country_id) REFERENCES DICTIONARIES(TYPE, ID)
)
Run Code Online (Sandbox Code Playgroud)

就可以有效解决这个问题。我知道我可以向表 person 添加列,该表只有一个可能的值“COUNTRY”,或者我可以编写一个触发器,但我宁愿避免这种情况以保持设计简洁。

sql postgresql foreign-keys

11
推荐指数
1
解决办法
3174
查看次数

Why am I getting a an error when creating a generated column in PostgreSQL?

CREATE TABLE my_app.person
(
    person_id smallserial NOT NULL,
    first_name character varying(50),
    last_name character varying(50),
    full_name character varying(100) generated always as (concat(first_name, ' ', last_name)) STORED,
    birth_date date,
    created_timestamp timestamp default current_timestamp,
    PRIMARY KEY (person_id)
);
Run Code Online (Sandbox Code Playgroud)

Error: generation expression is not immutable

The goal is to populate the first name and last into the full name column.

sql postgresql database-design string-concatenation calculated-columns

9
推荐指数
2
解决办法
4432
查看次数

生成加密的安全ID,而不是顺序标识/自动递增

我一直处于这种困境中一段时间​​,但是找不到任何提示,尽管似乎有人已经做到了。

我需要的是用加密的安全(即非连续!)ID替换顺序的AUTO_INCREMENT(或等效的)主键,但与此同时,我想保留顺序PK的性能优势:保证未使用的下一个ID,可集群性等。

一种简单的方法似乎实现了一种加密伪随机排列生成器,以将2 ^ N空间唯一地映射到2 ^ N,而不会发生冲突并且具有初始化矢量(IV)。

尽管可以在外部实现,但这确实需要存储和原子访问状态(排列位置或最后一个ID),这意味着从外部实现效率极低(这相当于UPDATE table SET crypto_id = FN_CRYPTO(autoincrement_id) WHERE autoincrement_id=LAST_INSERT_ID()为每个都运行后续操作INSERT)。

您是否知道在商业用途的数据库中有上述任何上述实现?

sql database cryptography

8
推荐指数
1
解决办法
246
查看次数

时间戳索引:索引表达式中的函数必须标记为 IMMUTABLE

我想在我的表上为start_time创建一个索引,这是我的 json 列中名为match的 timestamptz (带时区的时间戳)字段。

在这个问题这篇文章之后,我了解到由于不同的时区和本地化,您无法在 timestamptz 字段上创建索引。这两个都表明您可以在时间戳(转换为文本)上创建索引,因此我尝试了以下功能:

CREATE OR REPLACE FUNCTION to_text(timestamptz) 
 RETURNS text AS $$
  SELECT to_char($1 at time zone 'UTC', 'YYYY-MM-DD"T"HH24:MI:SS.US') 
  $$
LANGUAGE sql IMMUTABLE;
Run Code Online (Sandbox Code Playgroud)

我相信这与时区和本地化没有问题。

CREATE INDEX i_match_start_time ON matches (to_text(((match->>'start_time')::timestamptz)));
Run Code Online (Sandbox Code Playgroud)

这将返回以下内容:

错误:索引表达式中的函数必须标记为 IMMUTABLE

我还尝试过返回时间戳的函数:

SELECT ($1 at time zone 'UTC') 
Run Code Online (Sandbox Code Playgroud)

以及返回 unix 时间的函数(尝试了 double 并转换为十进制):

SELECT EXTRACT(EPOCH FROM $1)
Run Code Online (Sandbox Code Playgroud)

其中每个都返回相同的错误。

我需要在start_time上建立索引,因为实际上对该表的所有选择查询都将按start_time排序。

sql postgresql indexing datetime json

3
推荐指数
1
解决办法
5706
查看次数

PostgreSQL-错误:列不存在SQL状态:42703

我正在尝试进行队列分析,并根据承租人的第一个租赁年份(=承租人第一次租赁的年份)比较平均租金。基本上,我在问一个问题:我们是否保留第一年是2013年的房客而不是第一年是2015年的房客?

这是我的代码:

SELECT renter_id, 
       Min(Date_part('year', created_at)) AS first_rental_year, 
       ( Count(trip_finish) )             AS number_of_trips 
FROM   bookings 
WHERE  state IN ( 'approved', 'aboard', 'ashore', 'concluded', 'disputed' ) 
  AND  first_rental_year = 2013 
GROUP  BY 1 
ORDER  BY 1; 
Run Code Online (Sandbox Code Playgroud)

我收到的错误消息是:

ERROR:  column "first_rental_year" does not exist
LINE 6: ... 'aboard', 'ashore', 'concluded', 'disputed') AND first_rent...
                                                             ^

********** Error **********

ERROR: column "first_rental_year" does not exist
SQL state: 42703
Character: 208
Run Code Online (Sandbox Code Playgroud)

任何帮助深表感谢。

sql postgresql

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

如何向现有表添加串联列?

我正在尝试这个表达式,但我没有找到我的语法错误的地方:

alter table "TableName"
add column "NameColumn" as concat(ColumnA,ColumnB,ColumnC)
Run Code Online (Sandbox Code Playgroud)

所有三个字段都是字符变化的。

sql postgresql pgadmin

3
推荐指数
1
解决办法
6330
查看次数

如何获取 PostgreSQL 中表上所有索引的列名列表?

我有这个查询来获取表上的索引列表:

SELECT
    ns.nspname as schema_name,
    tab.relname as table_name,
    cls.relname as index_name,
    am.amname as index_type,
    idx.indisprimary as is_primary,
    idx.indisunique as is_unique
FROM
    pg_index idx
INNER JOIN pg_class cls ON cls.oid=idx.indexrelid
INNER JOIN pg_class tab ON tab.oid=idx.indrelid
INNER JOIN pg_am am ON am.oid=cls.relam
INNER JOIN pg_namespace ns on ns.oid=tab.relnamespace
WHERE ns.nspname = @Schema AND tab.relname = @Name
Run Code Online (Sandbox Code Playgroud)

它似乎工作正常。但现在我需要对列列表进行查询,但我无法理解系统视图的工作方式。

具体来说,我正在寻找的是:

  • [用于匹配第一个查询的索引名称或 id]
  • 索引中的顺序
  • 列名
  • 上升或下降
  • 排序列或包含列

理想情况下,我想一次获得给定表的所有索引的上述项目。


请注意,我正在寻找的不仅仅是列名。

postgresql database-metadata database-indexes

3
推荐指数
1
解决办法
2038
查看次数

数据库中的计算字段-Laravel

在数据库中存储计算字段的最佳实践是什么。

例如,假设一张桌子有高度,重量,体重指数等字段

用户输入身高体重值,并自动填写bmi字段。如何用表格实现。

bmi $ bmi的公式=体重/(身高*身高)

尝试了以下配置文件模型

protected $table = 'profiles';

protected $fillable = ['user_id', 'weight', 'height', 'dob', 'age', 'bmi'];

public function user(){
  return $this->belongsTo(User::class, 'user_id');
}

protected static function boot() {
  parent::boot();

  static::saving(function($model){
      $model->bmi = $model->weight / ($model->height * $model->height);
      $model->age = (date('Y') - date('Y',strtotime($model->dob)));
  });
}
Run Code Online (Sandbox Code Playgroud)

配置文件控制器

public function store(Request $request)
  {
      $profile = new Profile();
      $profile->weight = $request->get('weight');
      $profile->height = $request->get('height');
      $profile->dob = $request->get('dob');
      $profile->age;
      $profile->bmi;
      $profile->save();
      return back()->with('success', 'Your profile has been updated.');
  }
Run Code Online (Sandbox Code Playgroud)

但是我收到一个错误

Illuminate …
Run Code Online (Sandbox Code Playgroud)

laravel

1
推荐指数
3
解决办法
1632
查看次数

PostgreSQL 是否只支持 STORED 生成的列?

前言

我已经给出了一些来自 PHP 的例子,只是为了指出我的开发环境。问题不是关于 PHP,而是纯粹关于 PostgreSQL。


关于生成列的PostgreSQL文档指出:

生成的列有两种:存储的和虚拟的。存储的生成列在写入(插入或更新)时进行计算,并像普通列一样占用存储空间。虚拟生成列不占用存储空间,读取时进行计算。

但是,它只显示了该页面示例中存储列的示例,而不是虚拟列。它还说:

必须指定关键字 STORED 来选择生成列的存储类型。有关更多详细信息,请参阅创建表。

...链接到CREATE TABLE 页面的地方。在该页面中,文档明确指出模式是GENERATED ALWAYS AS (expression) STORED.

GENERATED ALWAYS AS ( generation_expr ) 存储

此子句将列创建为生成的列。该列无法写入,读取时将返回指定表达式的结果。

需要关键字 STORED 来表示该列将在写入时计算并将存储在磁盘上。

生成表达式可以引用表中的其他列,但不能引用其他生成的列。使用的任何函数和运算符都必须是不可变的。不允许引用其他表。

我实际上尝试在 Laravel (PHP) 中实现一个虚拟字段,这是我迄今为止在迁移中想到的:

DB::statement('ALTER TABLE entries ADD COLUMN do_hint BOOLEAN GENERATED ALWAYS AS (hint_hash OR hint_tags OR hint_due_date OR hint_created_at OR hint_updated_at) VIRTUAL');
Run Code Online (Sandbox Code Playgroud)

正如您在此语句中所见,表中有hint_hash,hint_tags和其他几个布尔列(以hint_*glob 模式命名)entries。我想计算do_hint即时,以便:

  • 我实际上可以从数据库中查询它。当然,我也可以在 PHP 上生成它,但我想查询,这就是我想使用虚拟列的一点。
  • 我想依靠 …

sql postgresql create-table generated-columns

0
推荐指数
1
解决办法
792
查看次数