2009-12-21 1 views
53

Я пишу приложение, которое берет данные пользователя и сохраняет его локально для использования позже. Приложение будет запущено и остановлено довольно часто, и я бы хотел, чтобы он сохранял/загружал данные в начало/конец приложения.Лучший способ хранения данных локально в .NET (C#)

Было бы довольно просто, если бы я использовал плоские файлы, так как данные действительно не нужно защищать (он будет храниться только на этом ПК). Варианты, я считаю, таким образом:

  • Плоские файлы
  • XML
  • SQL DB

Плоские файлы требуют немного больше усилий, чтобы поддерживать (не встроенные в классах, как с XML), однако Я раньше не использовал XML, и SQL кажется излишним для этой относительно простой задачи.

Есть ли другие возможности, которые стоит изучить? Если нет, то какое из них является лучшим решением?


Edit: Для того, чтобы добавить немного больше данных проблемы, в основном единственным, что я хотел бы сохранить это словарь, который выглядит как этот

Dictionary<string, List<Account>> 

где счета является другим пользовательским типом.

Могу ли я сериализовать dict как xmlroot, а затем тип учетной записи в качестве атрибутов?


Update 2:

Так что можно сериализовать словарь. Сложность заключается в том, что значение для этого dict является самим обобщением, который представляет собой список сложных структур данных типа Account. Каждая учетная запись довольно проста, это всего лишь куча свойств.

Это мое понимание того, что цель здесь заключается в попытке и в конечном итоге с этим:

<Username1> 
    <Account1> 
     <Data1>data1</Data1> 
     <Data2>data2</Data2> 
    </Account1> 
</Username1> 
<Username2> 
    <Account1> 
     <Data1>data1</Data1> 
     <Data2>data2</Data2> 
    </Account1> 
    <Account2> 
     <Data1>data1</Data1> 
     <Data2>data2</Data2> 
    </Account2> 
</Username2> 

Как вы можете видеть heirachy является

  • Имя пользователя (строка Словаре)>
  • Учетная запись (каждая учетная запись в списке)>
  • Данные учетной записи (т.е. свойства класса).

Получение этого макета с Dictionary<Username, List<Account>> является сложным битом и сутью этого вопроса.

Здесь много ответов «как» на сериализацию, это моя ошибка, так как я не делал ее более ясными на раннем этапе, но теперь я ищу определённое решение.

+0

дают больше ditails о том, какие приложения и хранятся данные, также excpected sizr –

+2

Для сериализации словаря: http://stackoverflow.com/questions/1111724 – Cheeso

ответ

20

Я бы сохранил файл как JSON. Поскольку вы храните словарь, который является только списком пар имя/значение, это в значительной степени предназначено для json.
Там немало приличных, бесплатных библиотек .NET json - вот one, но вы можете найти полный список по первой ссылке.

+0

json немного необычен для локального хранилища, но это, безусловно, отличное решение. Особенно с такой библиотекой, как Json.NET Newtonsoft – AFract

+0

, вместо того, чтобы полагаться на стороннюю библиотеку, я бы сохранил данные, используя встроенный тип набора данных, который очень прост для записи на диск (см. Ниже пример Тома Миллера) – docesam

13

XML прост в использовании, посредством сериализации. Используйте Isolated storage.

Смотрите также How to decide where to store per-user state? Registry? AppData? Isolated Storage?

public class UserDB 
{ 
    // actual data to be preserved for each user 
    public int A; 
    public string Z; 

    // metadata   
    public DateTime LastSaved; 
    public int eon; 

    private string dbpath; 

    public static UserDB Load(string path) 
    { 
     UserDB udb; 
     try 
     { 
      System.Xml.Serialization.XmlSerializer s=new System.Xml.Serialization.XmlSerializer(typeof(UserDB)); 
      using(System.IO.StreamReader reader= System.IO.File.OpenText(path)) 
      { 
       udb= (UserDB) s.Deserialize(reader); 
      } 
     } 
     catch 
     { 
      udb= new UserDB(); 
     } 
     udb.dbpath= path; 

     return udb; 
    } 


    public void Save() 
    { 
     LastSaved= System.DateTime.Now; 
     eon++; 
     var s= new System.Xml.Serialization.XmlSerializer(typeof(UserDB)); 
     var ns= new System.Xml.Serialization.XmlSerializerNamespaces(); 
     ns.Add("", ""); 
     System.IO.StreamWriter writer= System.IO.File.CreateText(dbpath); 
     s.Serialize(writer, this, ns); 
     writer.Close(); 
    } 
} 
+1

Это не очень компактен и не аккуратным –

+3

Это выглядит как вырезать-вставить код, чтобы вы могли стать первым плакатом. Было бы лучше просто придерживаться ваших ссылок. –

+7

Ну, да, я разрезал это прямо из приложения, которое я написал, что делает это. Робото, какая проблема? – Cheeso

21

Это действительно зависит от того, что вы храните. Если вы говорите о структурированных данных, то XML или очень легкие SQL RDBMS, такие как SQLite или SQL Server Compact Edition, будут хорошо работать для вас. Решение SQL становится особенно убедительным, если данные выходят за пределы тривиального размера.

Если вы храните большие куски относительно неструктурированных данных (например, двоичные объекты, такие как изображения), то, очевидно, ни база данных, ни XML-решение не подходят, но, учитывая ваш вопрос, я предполагаю, что это больше из первых, чем последний.

+1

Свободно доступный поставщик ADO.NET для SQLite http://sqlite.phxsoftware.com/ –

+0

Файлы конфигурации XML должны быть структурированы? –

+0

@Roboto: XML, по определению, структурирован. Это не значит, что вы должны использовать их в высокоструктурированном виде. –

0

Моим первым наклонением является база данных доступа. Файлы .mdb хранятся локально и могут быть зашифрованы, если это считается необходимым. Хотя XML или JSON также будут работать во многих сценариях. Плоские файлы я бы использовал только для чтения, а не для поиска (только для чтения). Я предпочитаю формат csv для установки ширины.

+1

Из любопытства, почему вы используете Access, если он уже не присутствовал или вам не нужен доступ к нему, ну, Access? В противном случае кажется, что облегченный SQL-движок будет более целесообразным, особенно с доступными в процессе параметрами, такими как SQLite и SQL Server CE. –

+0

JET-движок, который позволяет вам использовать файлы .MDB, я думаю, установлен с окнами, что делает использование файлов .MDB доступными как решение, и тот факт, что их легко вникнуть с доступом, если тебе нужно. Однако это предшествует текущей инкарнации SQL Server CE, которая может быть развертыванием .DLL «xcopy» и, следовательно, является лучшим способом достижения широко аналогичного результата. – Murph

+12

Друзья не позволяют друзьям использовать Access –

7

Четвертый вариант для тех, кого вы упомянули, - это двоичные файлы. Хотя это звучит загадочно и сложно, с API-интерфейсом сериализации в .NET это очень просто.

Независимо от того, выбираете ли вы двоичные или XML-файлы, вы можете использовать один и тот же API сериализации, хотя вы бы использовали разные сериализаторы.

Чтобы двоичный сериализовать класс, он должен быть отмечен атрибутом [Serializable] или реализовать ISerializable.

Вы можете сделать что-то подобное с XML, хотя интерфейс называется IXmlSerializable, и атрибуты [XmlRoot] и другие атрибуты в пространстве имен System.Xml.Serialization.

Если вы хотите использовать реляционную базу данных, то SQL Server Compact Edition является бесплатным и очень легким и основан на одном файле.

+0

Плоский файл! = Текстовый файл. Я бы подумал, что это подпадает под категорию «плоский файл». –

+2

Вы можете бинарно сериализовать класс независимо от того, имеете ли вы дело с XML-файлами –

+2

, если вам не нужен сериализованный объект, чтобы его можно было читать человеком, это самый надежный способ. Он сериализуется в крошечный файл и всегда казался самым быстрым способом сделать это с точки зрения быстродействия кода. И Марк прав, это кажется загадочным и трудным, но это совсем не так. И двоичная сериализация захватывает объект ENTIRE, даже его частные члены, которых нет в сериализации XML. – CubanX

0

Это зависит от объема, который вы ищете для хранения. На самом деле нет разницы между плоскими файлами и XML. XML, вероятно, будет предпочтительнее, поскольку он обеспечивает структуру документа. На практике

Последним вариантом и множеством приложений является реестр Windows. Я лично не рекомендую (Registry Bloat, Corruption, другие потенциальные проблемы), но это вариант.

+0

Одна область, где плоские файлы отличаются от XML, представляет собой иерархические данные. Конечно, вы можете представлять иерархии в плоских файлах, но это проще сделать в XML. – itowlson

8

Я рекомендую класс чтения/записи XML для файлов, потому что он легко сериализуется.

Serialization in C#

Сериализация (известная как травление в Python) является простым способом для преобразования объекта в двоичное представление, что затем может быть, например, записанный на диск или отправлен по проводу.

Полезно, например. для удобства сохранения настроек в файл.

Вы можете сериализовать свои собственные классы, если пометить их с [Serializable] атрибутом.Это сериализует все члены класса, за исключением тех, которые обозначены как [NonSerialized].

Ниже код, чтобы показать вам, как это сделать:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Drawing; 


namespace ConfigTest 
{ [ Serializable() ] 

    public class ConfigManager 
    { 
     private string windowTitle = "Corp"; 
     private string printTitle = "Inventory"; 

     public string WindowTitle 
     { 
      get 
      { 
       return windowTitle; 
      } 
      set 
      { 
       windowTitle = value; 
      } 
     } 

     public string PrintTitle 
     { 
      get 
      { 
       return printTitle; 
      } 
      set 
      { 
       printTitle = value; 
      } 
     } 
    } 
} 

Вы тогда, может быть, ConfigForm, вызовите класс ConfigManager и сериализовать его!

public ConfigForm() 
{ 
    InitializeComponent(); 
    cm = new ConfigManager(); 
    ser = new XmlSerializer(typeof(ConfigManager)); 
    LoadConfig(); 
} 

private void LoadConfig() 
{  
    try 
    { 
     if (File.Exists(filepath)) 
     { 
      FileStream fs = new FileStream(filepath, FileMode.Open); 
      cm = (ConfigManager)ser.Deserialize(fs); 
      fs.Close(); 
     } 
     else 
     { 
      MessageBox.Show("Could not find User Configuration File\n\nCreating new file...", "User Config Not Found"); 
      FileStream fs = new FileStream(filepath, FileMode.CreateNew); 
      TextWriter tw = new StreamWriter(fs); 
      ser.Serialize(tw, cm); 
      tw.Close(); 
      fs.Close(); 
     }  
     setupControlsFromConfig(); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

После того, как было сериализовать, вы можете назвать параметры файла конфигурации с использованием cm.WindowTitle и т.д.

+5

Просто уточнить: Serializable и NonSerialized не влияют на XmlSerializer; они используются только для System.Runtime.Serialization (например, двоичная сериализация).XmlSerializer сериализует публичные поля и свойства (read-write), а не внутреннее состояние: нет атрибута, необходимого для класса, и XmlIgnore вместо NonSerialized для исключения поля или свойства. – itowlson

+0

@itowlson: Правильно. Сериализация XML использует отражение для генерации специальных классов для выполнения сериализации. –

+0

Это поможет при чтении кода, если он был отступом без случайного размера ... –

0

Не зная, что выглядит ваши данные, как, например, сложность, размер и т.д. ..XML прост в обслуживании и легко доступен. Я бы не использовал базу данных Access, а плоские файлы сложнее поддерживать в течение длительного времени, особенно если вы имеете дело с более чем одним полем данных/элементом в вашем файле.

Я ежедневно обрабатываю большие плоские файлы данных в хороших количествах, и даже в крайнем примере данные с плоскими файлами гораздо сложнее поддерживать, чем обрабатываемые XML-каналы.

Простой пример загрузки данных XML в набор данных с помощью C#:

DataSet reportData = new DataSet(); 

reportData.ReadXml(fi.FullName); 

Вы также можете проверить LINQ к XML в качестве опции для запросов данных XML ...

НТН .. .

2

Я сделал несколько «самостоятельных» приложений, имеющих локальное хранилище данных. Я считаю, что лучше всего использовать SQL Server Compact Edition (ранее известный как SQLAnywhere).

Это легкий и бесплатный. Кроме того, вы можете придерживаться написания уровня доступа к данным, который можно использовать повторно в других проектах, плюс, если приложение когда-либо понадобится масштабировать до большего, чем полноразмерный SQL-сервер, вам нужно только изменить строку подключения.

0

Если вы идете по бинарной сериализации, рассмотрите скорость, с которой должен быть доступен конкретный член данных. Если это только небольшая коллекция, загрузка всего файла будет иметь смысл, но если она будет большой, вы можете также рассмотреть файл индекса.

Отслеживание свойств учетной записи/полей, расположенных по определенному адресу в файле, может помочь вам ускорить время доступа, особенно если вы оптимизируете этот индексный файл на основе использования ключа. (возможно, даже когда вы пишете на диск.)

3

Многие ответы в этой теме пытаются переопределить решение. Если я прав, вы просто хотите сохранить пользовательские настройки.

Для этого используйте файл .ini или файл App.Config.

Если я ошибаюсь, и вы храните данные, которые больше, чем просто настройки, используйте текстовый файл в формате csv. Это быстро и легко без накладных расходов на XML. Люди любят poo poo, так как они не такие элегантные, не красивы и не выглядят хорошими в резюме, но это может быть лучшим решением для вас в зависимости от того, что вам нужно.

+0

app.config vs custom XML: http://stackoverflow.com/questions/1565898/app-config-vs-custom-xml-file –

+0

Я делаю что-то немного сложнее, чем просто настройки. Каждый пользователь может иметь несколько «учетных записей», связанных с их именем. Словарь связывает это имя (строку) со списком связанных с ними учетных записей. Я бы сохранил кучу учетных записей для каждого пользователя. Он может работать с xml, но я не совсем уверен, как это сделать. – George

+0

В этом случае я бы использовал класс XmlSerializer, как указано. Если у вас есть хорошее понимание ООП, это должно быть легко. Вот хороший пример: http://www.jonasjohn.de/snippets/csharp/xmlserializer-example.htm – James

4

Если ваши данные сложны, имеют большое количество или вам необходимо запросить его локально, то объектные базы данных могут быть допустимыми. Я бы предложил посмотреть на Db4o или Karvonite.

10

Все вышесказанное является хорошим ответом и обычно решает проблему.

Если вам нужен простой, бесплатный способ масштабирования для миллионов частей данных, попробуйте проект управляемого интерфейса ESENT на CodePlex.

ESENT - это встраиваемый механизм хранения базы данных (ISAM), который является частью Windows. Он обеспечивает надежное, транзакционное, одновременное высокопроизводительное хранилище данных с блокировкой на уровне строк, протоколированием на основе записи и изоляцией моментальных снимков. Это управляемая оболочка API ESENT Win32.

У этого объекта PersistentDictionary, который довольно прост в использовании. Подумайте об этом как о объекте Dictionary(), но он автоматически загружается и сохраняется на диск без дополнительного кода.

Например:

/// <summary> 
/// Ask the user for their first name and see if we remember 
/// their last name. 
/// </summary> 
public static void Main() 
{ 
    PersistentDictionary<string, string> dictionary = new PersistentDictionary<string, string>("Names"); 
    Console.WriteLine("What is your first name?"); 
    string firstName = Console.ReadLine(); 
    if (dictionary.ContainsKey(firstName)) 
    { 
     Console.WriteLine("Welcome back {0} {1}", firstName, dictionary[firstName]); 
    } 
    else 
    { 
     Console.WriteLine("I don't know you, {0}. What is your last name?", firstName); 
     dictionary[firstName] = Console.ReadLine(); 
    } 

Чтобы ответить на вопрос Джорджа:

Поддерживаемые типы ключей

Только эти типы поддерживаются в качестве словаря ключей:

булевой байт Int16 UInt16 Int32 UInt32 Int64 uint64 Поплавок Double Guid DateTime TimeSpan Строка

Поддерживаемые типы значений

словарь значения могут быть любой из ключевых типов, Обнуляемые версии основных типов, Ури, IPAddress или сериализуемым структура , Структура является рассматривается только сериализации, если он отвечает всем этим критериям:

• Структура помечена как сериализации • Каждый член структуры является: 1. Примитивный тип данных (например, Int32) 2 . Строка, Uri или IPAddress 3. Сериализуемая структура.

Или, иначе говоря, сериализуемая структура не может содержать любые ссылки на объект класса. Этот выполнен для сохранения консистенции API. Добавление объекта в PersistentDictionary создает копию объекта, хотя и сериализуется. Изменение оригинального объекта не будет изменить копию, которая привела бы к запутанному поведению. Чтобы избежать ошибок , PersistentDictionary будет принимать значения только в качестве значений.

Может быть сериализован [Serializable] struct Хорошо { public DateTime?Получено; public string Name; общественная десятичная цена; общественный Uri Url; }

Нельзя сериализовать [Serializable] struct Bad { общественный байт [] Данные; // массивы не поддерживаются public Exception Error; // reference object}

+0

Этот метод в основном заменяет встроенный родословный постоянным словарем. Это довольно элегантное решение, но как оно обрабатывает сложные объекты, например, в примере OP? Хранит ли он все внутри дикта, или просто сам дикт? – George

+0

Это может упасть в конечном итоге, пытаясь сохранить списки типа Account. Ключ был бы прекрасен, но сделать универсальный сериализуемый может быть сложно: /. – George

+0

Любой, кто реализует это, может извлечь выгоду из знания того, что вы можете использовать Nuget для получения ManagedEsent. Затем вам нужно обратиться к Esent.Collections.DLL и Esent.ISAM.DLL. Затем добавьте «using Microsoft.Isam.Esent.Collections.Generic;» для получения типа PersistentDictionary. Сборники DLL, возможно, придется загружать из опций загрузки на http://managedesent.codeplex.com –

0

В зависимости от сложности объекта вашей учетной записи я бы рекомендовал либо XML, либо файл Flat.

Если есть только несколько значений для хранения для каждой учетной записи, вы можете хранить их на файл свойств, например:

account.1.somekey=Some value 
account.1.someotherkey=Some other value 
account.1.somedate=2009-12-21 
account.2.somekey=Some value 2 
account.2.someotherkey=Some other value 2 

... и так далее. Чтение из файла свойств должно быть простым, так как оно непосредственно сопоставляется с строковым словарем.

Что касается места хранения этого файла, лучшим выбором будет хранение в папке AppData внутри подпапки для вашей программы. Это место, где текущие пользователи всегда будут иметь доступ к записи, и он будет защищен от других пользователей самой ОС.

0

Держите его простым - как вы сказали, достаточно плоского файла. Используйте плоский файл.

Это предполагается, что вы правильно проанализировали свои требования. Я бы пропустил сериализацию как шаг XML, переполнил простой словарь. То же самое для базы данных.

4

Первое, что я хотел бы посмотреть, это база данных. Однако сериализация является опцией. Если вы идете на двоичную сериализацию, тогда я бы избегатьBinaryFormatter - у вас есть тенденция рассердиться между версиями, если вы меняете поля и т. Д. Xml через XmlSerialzier будет в порядке и может быть бок о бок совместимым (то есть с определения того же класса) с protobuf-net, если вы хотите попробовать двоичную сериализацию на основе контракта (без каких-либо усилий вы получаете плоский файловый сериализатор).

5

Если ваша коллекция становится слишком большой, я обнаружил, что сериализация Xml проходит довольно медленно. Другой вариант сериализации вашего словаря будет «сворачивать свой собственный» с помощью BinaryReader и BinaryWriter.

Вот пример кода, чтобы вы начали. Вы можете сделать эти общие методы расширения обработкой любого типа Словаря, и он работает достаточно хорошо, но слишком много для публикации здесь.

class Account 
{ 
    public string AccountName { get; set; } 
    public int AccountNumber { get; set; } 

    internal void Serialize(BinaryWriter bw) 
    { 
     // Add logic to serialize everything you need here 
     // Keep in synch with Deserialize 
     bw.Write(AccountName); 
     bw.Write(AccountNumber); 
    } 

    internal void Deserialize(BinaryReader br) 
    { 
     // Add logic to deserialize everythin you need here, 
     // Keep in synch with Serialize 
     AccountName = br.ReadString(); 
     AccountNumber = br.ReadInt32(); 
    } 
} 


class Program 
{ 
    static void Serialize(string OutputFile) 
    { 
     // Write to disk 
     using (Stream stream = File.Open(OutputFile, FileMode.Create)) 
     { 
      BinaryWriter bw = new BinaryWriter(stream); 
      // Save number of entries 
      bw.Write(accounts.Count); 

      foreach (KeyValuePair<string, List<Account>> accountKvp in accounts) 
      { 
       // Save each key/value pair 
       bw.Write(accountKvp.Key); 
       bw.Write(accountKvp.Value.Count); 
       foreach (Account account in accountKvp.Value) 
       { 
        account.Serialize(bw); 
       } 
      } 
     } 
    } 

    static void Deserialize(string InputFile) 
    { 
     accounts.Clear(); 

     // Read from disk 
     using (Stream stream = File.Open(InputFile, FileMode.Open)) 
     { 
      BinaryReader br = new BinaryReader(stream); 
      int entryCount = br.ReadInt32(); 
      for (int entries = 0; entries < entryCount; entries++) 
      { 
       // Read in the key-value pairs 
       string key = br.ReadString(); 
       int accountCount = br.ReadInt32(); 
       List<Account> accountList = new List<Account>(); 
       for (int i = 0; i < accountCount; i++) 
       { 
        Account account = new Account(); 
        account.Deserialize(br); 
        accountList.Add(account); 
       } 
       accounts.Add(key, accountList); 
      } 
     } 
    } 

    static Dictionary<string, List<Account>> accounts = new Dictionary<string, List<Account>>(); 

    static void Main(string[] args) 
    { 
     string accountName = "Bob"; 
     List<Account> newAccounts = new List<Account>(); 
     newAccounts.Add(AddAccount("A", 1)); 
     newAccounts.Add(AddAccount("B", 2)); 
     newAccounts.Add(AddAccount("C", 3)); 
     accounts.Add(accountName, newAccounts); 

     accountName = "Tom"; 
     newAccounts = new List<Account>(); 
     newAccounts.Add(AddAccount("A1", 11)); 
     newAccounts.Add(AddAccount("B1", 22)); 
     newAccounts.Add(AddAccount("C1", 33)); 
     accounts.Add(accountName, newAccounts); 

     string saveFile = @"C:\accounts.bin"; 

     Serialize(saveFile); 

     // clear it out to prove it works 
     accounts.Clear(); 

     Deserialize(saveFile); 
    } 

    static Account AddAccount(string AccountName, int AccountNumber) 
    { 
     Account account = new Account(); 
     account.AccountName = AccountName; 
     account.AccountNumber = AccountNumber; 
     return account; 
    } 
} 
+0

Спасибо, это выглядит как лучшее решение. Что вы подразумеваете под синхронизацией с Deserialize/Serialize? Как при обновлении файла при его изменении? Эта функция будет использоваться только при запуске и выходе приложения для сохранения dict, так что вы могли бы прояснить это? Иначе спасибо большое. – George

+0

Подумав об этом немного, я понял, что логика сериализации и десериализации должна быть одинаковой. Вот и все. – George

+0

Да, это все это значит. Поэтому, если вы добавите другое свойство для сериализации/десериализации, просто имейте в виду, что вам нужно добавить код для метода Serialize/Deserialize и сохранить их в том же порядке. Немного поддержки, но производительность по сравнению с серией Xml не сравнивается (несколько минут для десериализации с использованием xml, до пары секунд с использованием BinaryReader с несколькими сотнями тысяч позиций словаря). – GalacticJello

5

Только что закончил хранение данных кодирования для моего текущего проекта. Вот мои 5 центов.

Я начал с бинарной сериализации. Он был медленным (около 30 секунд для загрузки 100 000 объектов), и он также создавал довольно большой файл на диске. Однако мне потребовалось несколько строк кода для реализации, и я получил все мои потребности в хранилищах. Чтобы повысить производительность, я перешел на пользовательскую сериализацию. Найденная система FastSerialization Тимом Хейнсом в проекте Code. Действительно, он в несколько раз быстрее (получил 12 секунд для загрузки, 8 секунд для сохранения, 100K записей), и он занимает меньше места на диске.Структура основана на технике, описанной GalacticJello в предыдущем посте.

Затем я перешел на SQLite и смог получить 2 раза в 3 раза быстрее - 6 секунд для загрузки и 4 секунды для сохранения, 100 тыс. Записей. Он включает в себя анализ таблиц ADO.NET для типов приложений. Это также дало мне гораздо меньше файлов на диске. В этой статье объясняется, как получить лучшую производительность из ADO.NET: http://sqlite.phxsoftware.com/forums/t/134.aspx. Создание инструкций INSERT - очень плохая идея. Вы можете догадаться, как я узнал об этом. :) Действительно, реализация SQLite заняла у меня довольно много времени, а также тщательное измерение времени, которое занимает почти каждая строка кода.

0

По моему опыту в большинстве случаев достаточно JSON в файле (в основном вам нужно хранить массив или объект или только один номер или строку). Мне редко нужен SQLite (для этого требуется больше времени для его настройки и использования, в большинстве случаев это слишком много).

Смежные вопросы