我想使用Postgres数组存储每个发件人的事件。 每个事件都将保留为Postgres自定义类型(对象)。
如何通过自定义类型属性查询记录?有可能吗?
如果是,我可以在数组列上放置任何索引类型以加快查询速度吗?
创建自定义类型:
CREATE TYPE sender_event AS (
event_timestamp TIMESTAMP(3),
message TEXT
);
使用自定义类型数组创建表:
CREATE TABLE sender_history (
sender varchar(30),
events sender_event[]
);
在表中插入几条记录:
INSERT INTO sender_history VALUES
('sender1', ARRAY[(now(), 'Message text 1')::sender_event]),
('sender2', ARRAY[(now(), 'Message text 2')::sender_event])
如何查找“事件”数组包含“消息”属性等于“消息文本2”的对象的所有记录?
例如像这样的东西(这不起作用):
SELECT * FROM sender_history
WHERE events.message = 'Message text 2'
预期结果应该是该表中的第二条记录。
答案 0 :(得分:1)
如果要应用条件,则需要取消嵌套这些数组:
SELECT sh.*
FROM sender_history sh
WHERE exists (select *
from unnest(sh.events) as x
where x.message = 'Message text 2');
但这最好存储在正确归一化的一对多关系中。
https://www.amazon.com/apple-app-site-association
未设置数组;搜索特定的数组元素可能是数据库设计错误的标志。考虑使用单独的表,其中每个项都将有一个行作为数组元素。这将更容易搜索,并且可能会针对大量元素进行更好地缩放。
答案 1 :(得分:1)
搜索数组中的某个元素之前,您需要使用import { ClientFunction, t, Selector, RequestLogger } from 'testcafe'
import * as fs from 'fs';
import * as path from 'path';
...
const forInvoice = new ForInvoice()
const client = 'STRV s.r.o.'
const url = urlFor('?/timers/unbilledOverview')
const logger = RequestLogger({ url, method: 'post' }, {
logResponseHeaders: true,
logResponseBody: true
});
fixture.only `For Invoicing`
.requestHooks(logger);
test('Verify download of .xls and .pdf', async t => {
await t.useRole(ADMIN_INVOICE)
await forInvoice.navigateToForInvoicing()
await forInvoice.filterClient(client)
await t
.click(Selector('a').filter('.sc-mini-icon-file.excel-file'))
.expect(logger.contains(r => r.response.statusCode === 200)).ok();
const filePath = path.join(__dirname, 'STRV-s-r-o-Attachment');
console.log(filePath);
console.log(logger.requests[0].response.headers);
fs.writeFileSync(filePath, logger.requests[0].response.body);
})
对其进行扩展:
unnest()
但是,尽管如此,我还是建议不要在这种情况下使用自定义类型。相反,正如@a_horse_with_no_name所说,您应该规范化您的表结构。