web-dev-qa-db-ja.com

Sqlite3の1列に配列を保存する方法は?

テーブルの1列に整数の配列を格納する方法はありますか?私はこのようなO/Pが欲しい:

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

これは私はすでにpostgresで達成していますが、sqliteからも同じo/pが欲しいです。ここで、列の値は配列を格納します。 BLOBで試してみましたが、機能していません。誰かがシリアル化された方法について私に言ったが、私はそれを行う方法がわからない。

27
SPK

SQLite3は配列を直接サポートしていません。 here がサポートするタイプを参照してください。基本的に、Ints、Floats、およびTextのみを実行します。

必要なものを実現するには、カスタムエンコーディングを使用するか、FKを使用する必要があります。つまり、配列内の各アイテムが行として格納される別のテーブルを作成する必要があります。

23
Gianni

Necroに申し訳ありませんが、問題を自分で見つけて解決策を見つけました。

すでに述べたように、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();

}

これにより、配列が単一の文字列に変わります。文字列を取得して、テーブルに文字列として挿入します。文字列を読み取るときに、このコードを使用して配列を取得します。別のC#の例

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

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

これは、1次元配列でのみ機能します。多次元は、文字列の解析に関して扱いにくい場合があります。

13
Fornoreason1000

これは、データをシリアル化および逆シリアル化する1つの方法です。

#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としてシリアル化して、逆シリアル化されたデータを処理するときに2つずつ読み取ることができます。

2
nurettin

これは間違っているかもしれませんが、私が想定しているものです。

<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>
1
Wolfpack'08