如何在Postgres表中正确存储C#的Bitarray

时间:2019-12-10 19:23:35

标签: c# postgresql bitarray

当前,我正在尝试将可变长度的位模式存储在Postgres表中。我的用例是,我想以紧凑的方式对有关分配给组的数据记录的一些信息进行编码。

我在Postgres中的表格的简化模式如下:

CREATE TABLE axivas.group_records (
id int4 NOT NULL GENERATED ALWAYS AS IDENTITY,
record_id int4 NOT NULL,
group_ids varbit(50) NOT NULL,
CONSTRAINT group_records_pkey PRIMARY KEY (id));

在C#应用程序中,我像这样使用Npgsql Entity FrameworkCore创建实体:

try
{
     var context = new xerxesdevtestsContext();

     Random rnd = new Random();

     for (int i = 0; i < 1024; i++)
     {

        BitArray ba = new BitArray(rnd.Next(10, 50));
        ba.SetAll(false);
        for (int j=rnd.Next(0,5);j<rnd.Next(5,ba.Length-1);j++)
        {
            ba[j] = true;
        }
        context.GroupRecords.Add(new GroupRecords()
        {
            GroupIds = ba,
            RecordId = i
        });

     }
     context.SaveChanges();
 }
 catch (Exception ex)
 {
     Console.WriteLine("Error: " + ex.Message);
 }

随机添加随机数,用于设置位的数量和位数组的长度。

当我查看存储的数据时,可以看到在某些情况下,位串以前导零存储,在其他情况下,省略了前导零(我附加了screenshot来显示这一点)。换句话说,在某些情况下,DBeaver显示的值为“ 0000110110111110000 .....”,在其他情况下,显示的值为“ 1100111 ...”。

所以我的问题是,如何解释这一点以及是否有必要完全省略位串中的前导零?

任何想法或其他信息将不胜感激。

更新: 我更改了表格中位字符串的大小,并

将该位数组中的各个位设置为1并再次进行测试的算法。我的更改具有以下效果:

  1. 位数组将从最高索引开始填充。
  2. 在结果事件中,可以观察到更多的前导零;例如这是结果记录之一:
  

| 3104 | 702 | 0000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111110 |

我认为这种情况清楚地说明了为什么我要省略前导零。

最诚挚的问候,

迈克尔

1 个答案:

答案 0 :(得分:1)

您的位数组具有前导零的原因似乎很明显,这是因为在您的for循环中,j被初始化为一些很少为零的值。 j始终必须为零,才能开始在数组的开头放置1。否则,在大多数情况下,您将以前导零结尾。

因此,如果您想要可变长度的随机二进制数,为什么不这样做:

BitArray ba = new BitArray(rnd.Next(10, 50));

ba.SetAll(false);
ba[0] = true;

for (int j = 1; j < ba.Length - 1; j++)
{
    ba[j] = Convert.ToBoolean(rnd.Next(2));
}

创建的示例值:

100110101001000011111100110100010101100110110
111101100110001101001100111101001100011110
1010101111000100
1011001010001000010100
101001101001010100101110000001000111001010