Как сохранить массив в одном столбце в Sqlite3?
Есть ли способ сохранить массив целых чисел в одном столбце таблицы? Я хочу o/p следующим образом:
ident | value | count
----------------+------------------------------------------------------------------------------------------------------------------------+-------
563 | [0:10]={"(0,0)","(1,100)","(2,200)","(3,300)","(4,400)","(5,500)"} | 6
Это я уже получил через postgres, но я хочу, чтобы у него был такой же o/p из sqlite.
Здесь значение столбца хранит массив. Я пробовал его через BLOB, но он не работает. Кто-то рассказал мне о сериализованном способе, но я не уверен, как это сделать.
Ответы
Ответ 1
SQLite3 не поддерживает массивы напрямую. См. здесь, который он поддерживает. В основном, это только Ints, Floats и Text.
Чтобы выполнить то, что вам нужно, вы должны использовать пользовательскую кодировку или использовать FK, т.е. создать другую таблицу, где каждый элемент массива хранится в виде строки.
Ответ 2
Извините, что Necro просто может решить проблему самостоятельно и нашел решение.
Как уже говорилось, SQLite не поддерживает массивы, поэтому вы не можете хранить их как таковые.
Попробуйте это, у меня была та же проблема;
вместо хранения элементов массива индивидуально, вы можете разорвать их как большую строку и использовать функцию строки или регулярное выражение для их повторного анализа в своих типах. Пример С#
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);
это будет работать только с одномерными массивами, многоэлементный может оказаться сложным, когда дело доходит до разбора строк.
Ответ 3
Это один из способов сериализации и десериализации данных:
#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 и читать два на два при обработке десериализованных данных.
Ответ 4
Это то, что я представляю, хотя это может быть неверно:
<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>