Lor*_*sum 3 postgresql centos-7 postgresql-9.5
将数据加载到表中时,出现以下错误:
ERROR: row is too big: size 8680, maximum size 8160
Run Code Online (Sandbox Code Playgroud)
该表中有 1000 多列,这似乎是问题所在。一般的互联网建议是“重构!” 或“正常化!”。例如,这篇文章。不幸的是,我不相信这样的建议适用于我的情况。
该表用于存储从设备收集的数据。作为分析的一部分,设备会生成 PNG 图像。PNG 包含 1024 个像素。每个像素都有一个关联的数值。与像素数据一起的是与分析相关的各种其他领域。把桌子分成几部分真的没有意义。这些字段都与正在分析的特定对象在逻辑上相关联。
Postgres 似乎不喜欢每个像素都有自己的字段。该表具有以下形式的字段:pixel_1
, pixel_2
, ..., pixel_1024
。注意,这是从通常的例子有着根本的不同phone_number_1
,phone_number_2
等每个像素是由于其位置的一个唯一的对象。 pixel_1
具有不同的位置,pixel_123
并且每个像素都有一个相关联的值。它们之间的共同点是它们都用于描述相同的分析对象。它们是 PNG 中给出的视觉表示的定量模拟。
我希望我已经把上下文说清楚了。我试图将问题归结为它的本质,但我怀疑可能需要进行一些澄清。如果需要澄清,请告诉我。
编辑:作为一项实验,我尝试将像素分解为单独的表格。这似乎是唯一可能的重构方式。但是 1024 列会产生相同的错误。
该表用于存储从设备收集的数据。作为分析的一部分,设备会生成一个 PNG 图像。PNG 包含 1024 个像素。每个像素都有一个关联的数值。与像素数据一起的是与分析相关的各种其他领域。把桌子分成几部分真的没有意义。这些字段都与正在分析的特定对象在逻辑上相关联。
这称为“光栅”,而不是 PNG 图像。PNG 实际上是使用 DEFLATE 压缩存储的 RGB[A] 栅格,但您要存储的内容与它是 PNG 无关。如果这些术语没有意义,就像告诉某人您要存储 PDF 一样。这是可能的,但很可能他们想要的是存储底层文本。
这里来自 PNG 的底层文本是光栅。
PostgreSQL 支持使用 PostGIS 存储实际的栅格类型。我建议查看PostGIS Raster Reference。如果您的栅格当前在 PNG 通道中编码,则可以使用GDAL 将它们放入数据库中
我建议查看有关如何查询、处理、修改和导出栅格数据的信息。
即使您决定不使用 PostGIS,我也不相信其他答案就足够了。如上所述,RGB 像素是一种 3 通道复合数据类型。因此,像素数据至少需要三个维度。
此外,您可能需要有关 XY 像素数据的信息,或者稍后使用该元数据进行计算的方法。
您可以使用立方体来表示像素数据
-- white and black pixels (RGB)
SELECT ARRAY['(255,255,255)','(0,0,0)']::cube[]
Run Code Online (Sandbox Code Playgroud)您可以使用数组来存储每个通道(可能对处理没有用),并且导入和导出将很困难。
您可以为像素使用类型。,尽管记录类型甚至"char"
比我们下面的解决方案大得多。
您可以将每个像素存储为一个int
并忽略通道(假设您的 1 字节通道少于四个)。如果你需要处理这会很快变得非常丑陋,使分析几乎不可能,并且导出和查询非常困难。
或者您可以创建自己的DOMAIN
,但此时您基本上是在重新创建 PostGIS 的栅格。通过这种方法,您可以将所有四个波段存储为一个整数。以最低成本访问这些波段,并从波段构建像素。int8
如果您需要 8 个频段,您可以轻松地将其扩展到。
CREATE DOMAIN pixel AS int4;
CREATE OR REPLACE FUNCTION get_band(p pixel, b int)
RETURNS int AS $$
SELECT ((p::bit(32)<< ((4-b)*8)) >> (3*8))::int
$$ LANGUAGE sql
IMMUTABLE;
CREATE OR REPLACE FUNCTION create_pixel( int, int, int, int )
RETURNS pixel AS $$
SELECT (
$1::bit(32) |
($2::bit(32)<<8) |
($3::bit(32)<<16) |
($4::bit(32)<<24)
)::pixel;
$$ LANGUAGE sql
IMMUTABLE;
-- Returns 128.
SELECT get_band(create_pixel(255,0,128,32),3)::int;
-- You can use this type in an array too
CREATE TABLE f ( ps pixel[] );
Run Code Online (Sandbox Code Playgroud)附带说明,如果使用 LIDAR,您应该查看PG Point Cloud
归档时间: |
|
查看次数: |
889 次 |
最近记录: |