如何在SQLITE3中存储一列中的数组?

mlnl4t2r  于 2022-11-15  发布在  SQLite
关注(0)|答案(6)|浏览(990)

有没有办法将整数数组存储在表的一列中?我想要这样的订单:

ident | value                                                            | count 
----------------+------------------------------------------------------------------------------------------------------------------------+-------
563 | [0:10]={"(0,0)","(1,100)","(2,200)","(3,300)","(4,400)","(5,500)"} |    6

我已经通过Postgres获得了这一点,但我也希望从SQLITE获得同样的O/P。在这里,列值存储一个数组。我用BLOB试了一下,但不起作用。有人告诉我序列化的方式,但我不确定如何做到这一点。

bwitn5fc

bwitn5fc1#

Sqlite3不直接支持数组。请参见here它支持的类型。基本上,它只处理整数、浮点数和文本。
要实现所需的功能,您必须使用自定义编码,或使用FK,即创建另一个表,其中数组中的每一项都存储为一行。

beq87vna

beq87vna2#

SQLite不支持数组,因此您不能这样存储它们。您可以将数组元素存储为单个字符串,并使用字符串函数或正则表达式将它们解析回其类型,而不是单独存储数组元素。
C#示例:

int[] myArray = new int[] {8,4,345,378,34456,7};

string Arraystring = myArray[0].ToString();

for(int i = 1; i < myArray.Length; i++) { 
    Arraystring += "," + myArray[i].ToString();
}

这会将数组转换为单个字符串,现在将其作为字符串插入。要取回数组,请执行以下操作:

string value; //assign this via Reader
string[] tokens = values.Split(',');

int[] myItems = Array.ConvertAll<string, int>(tokens, int.Parse);

这只适用于一维数组,多维数组在解析字符串时可能会变得很棘手。

rqqzpn5f

rqqzpn5f3#

这是序列化和反序列化数据的一种方式:

#include <string>
#include <vector>
#include <sstream>
#include <iostream>

std::vector<std::string> deserialize_array(std::string const &csv)
{
  std::istringstream parse(csv);
  std::vector<std::string> ret;
  for(std::string token; std::getline(parse, token, ','); ret.push_back(token));
  return ret;
}

std::string serialize_array(std::string* array_ptr, std::size_t N)
{
  std::ostringstream cat;
  for(std::size_t index= 0; index< N; ++ index)
    cat<< array_ptr[index]<< ',';
  std::string ret= cat.str();
  return ret.substr(0, ret.size()-1);
}

int main()
{
  std::string data= "1,2,3";
  std::cout<< "Data: "<< data<< std::endl;
  std::vector<std::string> deserialized= deserialize_array(data);
  std::string serialized= serialize_array(deserialized.data(), deserialized.size());
  std::cout<< "Serialized + Deserialized: "<< serialized<< std::endl;
}

无需花费时间解析圆括号和额外的逗号,您可以将其序列化为CSV,并在处理反序列化数据时逐个读取。

yfjy0ee7

yfjy0ee74#

您可以使用JSON.stringify,当您再次读取数据时,可以使用JSON.parse。因此,您可以将数组存储为字符串,并可以轻松地将其再次解析回数组。通过这种方式,还可以将数组的数组放入sqlite db。

ecfdbz9o

ecfdbz9o5#

这是我的设想,尽管它可能是不正确的:

<table>
  <citation>
    <citation ID>
    <citation content>
    <citation publication date>

CREATE TABLE citation
(
    citation_ID INTEGER PRIMARY KEY AUTOINCREMENT,
    citation VARCHAR(255)
    published datetime
    )

<table>
  <source doc>
    <source doc ID>
    <source doc content>

CREATE TABLE source
(
    source_ID INTEGER PRIMARY KEY AUTOINCREMENT,
    source VARCHAR(5000)
    )

<citation_to_source table> //table in question
  <relationship>
    <relationship ID>
    <citation ID>
    <source doc ID>

CREATE TABLE citation_to_source //table in question
(
    relationship_id INTEGER,
    citation_ID INTEGER,
            source_ID INTEGER,
            FOREIGN KEY(citation_ID) REFERENCES citation(citation_ID)
            FOREIGN KEY(source_ID) REFERENCES source(source_ID)
    )

输出格式:

<content>
  <relationship ID>
  <unique source document content>
  <enumerate citation IDs>
liwlm1x9

liwlm1x96#

我也在处理同样的问题。我来自JS,但我认为这将是一个跨语言的答案。由于没有人给出Gianni想法的代码示例,而Wolfpack‘08正在询问示例,我将留下我的解决方案。

SELECT A.artistid, B.name, group_concat(A.title, '   --   ') titlesList 
FROM albums A
INNER JOIN artists B
ON A.artistid = B.artistid
GROUP BY A.artistid
LIMIT 10
;
  • 备注:
  • 我使用SQLite Studio来获得更好的视觉显示,并为示例使用chinook.db数据库。
  • A和B是表的别名,以避免名称不明确。
  • 我使用‘--’输出空格列表。
  • 数据库资源:
  • https://www.sqlitetutorial.net/sqlite-sample-database/
  • 文档:内置聚合函数:GROUP_CONCAT(X,Y)
  • https://www.sqlite.org/lang_aggfunc.html#group_concat

相关问题