Каков наилучший способ сохранить почти статические данные для веб-приложения? - PullRequest
3 голосов
/ 27 декабря 2010

Я создаю веб-приложение на Python.Часть этого приложения работает с данными, которые можно описать следующим образом:

Symbol     Begin Date      End Date
AAPL       Jan-1-1985      Dec-27-2010
...

Данные несколько статичны - они будут периодически обновляться, то есть могут добавляться новые записи иПоле «Дата окончания» может быть обновлено для всех записей.

Теперь вопрос: учитывая более или менее статическую природу набора данных, каков наилучший способ его хранения и работы с ним?«Работать» означает извлекать случайные строки, надеюсь, чаще, чем несколько раз в секунду.

Я могу сделать это с файлом XML, с базой данных SQL или SQLite, с файлом объекта JSON и каким-либо объектом python в памяти.1008 *

Каковы минусы и плюсы разных решений?Я буду благодарен за объяснения и за крайние случаи (например, «до тех пор, пока XML-файл не станет лучшим после 10 раз в секунду, после этой базы данных SQL).

Обновление: Спасибо за все ответы!Просто небольшое обновление: в настоящее время набор составляет около 3 тыс. Строк.Это может вырасти, скажем, до 15 тысяч строк в год.Схема доступа: обновления являются регулярными, один раз в день, для полной комплектации;поэтому добавление строк и обновление даты окончания будут выполнены одновременно.Получение случайной строки действительно по символу, может быть сделано несколько раз в секунду.

Ответы [ 6 ]

3 голосов
/ 27 декабря 2010

Я бы генерировал исходный файл Python каждый раз, когда изменялись данные, и имел бы этот файл, состоящий в основном из словаря.Это предполагает, что поиск выполняется по символу, и что данные легко помещаются в память.

data = {
  "AAPL":       ("Jan-1-1985",      "Dec-27-2010"),
...
}

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

Редактировать : Чтобы проиллюстрировать, как можно записать такой файл, вот скрипт, который заполняет его случайными данными

import random, string, pprint

def randsym():
    res =[]
    for i in range(4):
        res.append(random.choice(string.uppercase))
    return ''.join(res)

months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
          'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
days = range(1,29)
years = range(1980,2010)
def randdate():
    return "%s-%s-%s" % (random.choice(months),
                         random.choice(days),
                         random.choice(years))

data = {}
for i in range(15000):
    data[randsym()] = (randdate(), "Dec-27-2010")

with open("data.py", "w") as f:
    f.write("data=")
    f.write(pprint.pformat(data))

Чтобы получить доступ к данным, выполните from data import data.

0 голосов
/ 28 декабря 2010

Мое понимание проблемы: SQL масштабируется, большая часть работы выполняется за вас.Если вы понимаете SQL, вероятно, это (98%) путь.

CSV-файлы: они становятся уродливыми на жестком диске, когда вы имеете дело с более чем несколькими (12 раз)доступ в секунду.ОДНАКО - если данные имеют разумный размер, рассмотрите возможность использования оперативного привода, вы можете разделить данные на файлы и обращаться к ним со скоростью с невероятной скоростью .Много маленьких файлов, нет проблем.Но вам нужно убедиться, что любые данные, которые нужно сохранить, сохраняются в реальном магнитном хранилище или на SSD.CSV-файлы на SSD вы можете смотреть на 1000 обращений в секунду, если данные достаточно малы.С некоторыми хорошими именами файлов и достаточно маленьким набором данных это может быть приемлемым вариантом.

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

0 голосов
/ 27 декабря 2010

Я бы избегал XML, так как он потребует большего разбора, а его преимущества не приносят пользы таблицам. Кроме того, я бы избегал словарей, если вам нужно больше, чем однозначное сопоставление (т. Е. AAPL появляется дважды или более). Если наборы данных относительно невелики, я бы предложил CSV, поскольку их просто смешно использовать в виде списка:

import csv

myList = []
myReader = csv.reader(open("your_file.csv", "rb"))
for row in reader:
    myList.append(row)
...do stuff...
myWriter = csv.writer(open("your_file.csv", "wb"))
myWriter.writerows(myList)

Если вам нужна чистая скорость, эффективность и масштабируемость, нет никакой параллели с SQL, какой бы формы вы ни выбрали. Между различными формами SQL (MySQL, MSSQL, Postgre и т. Д.) Различия относительно невелики по сравнению с различием между SQL в целом и CSV или XML.

Я сказал «относительно мало» для CSV, потому что нет жесткого и быстрого правила, которое я могу вам дать. Это зависит от целого ряда факторов, но все, что выше нескольких МБ, вероятно, будет заметно быстрее через SQL во многих системах.

0 голосов
/ 27 декабря 2010

Даже будучи почти статичным, вы можете сортировать, искать и фильтровать, так что речь идет не только о сохранении.Практически любое решение с возможностью чтения и записи за один раз порадует вас, включая:

  • SQLite
  • MySQL
  • Базы данных ключ / значение

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

0 голосов
/ 27 декабря 2010

Получение случайных строк по символу и не много данных? Вам нужна какая-то индексация. При запуске веб-приложения сохраните его в файле, читаемом Python из источника (файл csv?), И перезапустите веб-приложение при изменении данных.

Получение случайных строк по номеру строки и это не много данных? При запуске веб-приложения сохраните его в виде списка кортежей, считанных из источника (файл csv?), И перезапустите веб-приложение при изменении данных.

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

0 голосов
/ 27 декабря 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...