В общем, Pandas делает «равные соединения» легкими, но другие виды довольно трудны. В этом случае вам повезло, так как есть хороший метод под названием merge_asof
, который должен делать то, что вам нужно.
Это немного педантично в отношении того, как настроены ваши данные, но MWE:
from io import StringIO
import pandas as pd
df1 = pd.read_table(StringIO("""1 object_name time_epoch_ms source data
2 a 1538518822490 source_1 some_data_1
3 b 1538528822490 source_2 some_data_2
4 b 1538538822490 source_2 some_data_3
5 b 1538548822490 source_3 some_data_4
6 b 1538558822490 source_1 some_data_5
7 c 1538568822490 source_2 some_data_6
8 c 1538578822490 source_2 some_data_7
9 c 1538588822490 source_2 some_data_8
"""), sep=r"\s+", index_col=0)
df2 = pd.read_table(StringIO("""1 object_name time_epoch_ms new_data
2 a 1538518722490 x
3 b 1538528822490 y
4 b 1538518922490 z
5 b 1538519922490 a
6 b 1538598822490 b
7 c 1538548822490 c
8 c 1538538822490 c
9 c 1538528822490 d
"""), sep=r"\s+", index_col=0)
pd.merge_asof(
df2.sort_values(['time_epoch_ms', 'object_name']),
df1.sort_values(['time_epoch_ms', 'object_name']),
by="object_name", on="time_epoch_ms",
direction='forward',
).sort_values(['object_name', 'time_epoch_ms'])
, что возвращает:
object_name time_epoch_ms new_data source data
0 a 1538518722490 x source_1 some_data_1
1 b 1538518922490 z source_2 some_data_2
2 b 1538519922490 a source_2 some_data_2
3 b 1538528822490 y source_2 some_data_2
7 b 1538598822490 b NaN NaN
4 c 1538528822490 d source_2 some_data_6
5 c 1538538822490 c source_2 some_data_6
6 c 1538548822490 c source_2 some_data_6
См. Панд эквивалентно SQL non-equi JOIN для другого примера. Есть также merge_ordered
, но я не думаю, что это поможет вашему делу.
Преимущество того, чтобы хранить данные в DB использует в своих интересах механизмы защиты DB и уменьшает стоимость maintanence (резервные копии...). Недостаток его увеличивает загрузку DB и использует соединения (который мог бы быть дорогим для лицензированных серверов баз данных для каждого подключения). При использовании SQL Server, 2008, FILESTREAM
мог бы быть хорошей альтернативой.
Между прочим, для веб-приложений (или любые другие приложения, которым, возможно, понадобилась бы потоковая передача данных), обычно более разумно хранить данные вне DB.
Самый большой недостаток при хранении БЛОБОВ, является потреблением памяти. Можно ли вообразить то, что выбор * от x сделал бы для тысяч записей с изображением 45k в каждом?
, Поскольку Mehrdad, сказанные там, являются также преимуществами. Таким образом, если Вы решаете пойти с тем подходом, необходимо попытаться разработать базу данных так, чтобы большинство запросов возвратило меньше результатов с данными BLOB в них. Возможно, например, сделайте связи "один к одному" с этой целью.
Я знаком с довольно большим проектом OSS, который принял решение в его начале для хранения изображений в базе данных MySQL, и это, как доказывают, среди лучших 3 плохих идей, с которыми они справлялись с тех пор. (Усиленный фактом "осуществляют рефакторинг беспощадно", анафема, но это - другая история.)
Среди серьезных проблем это вызвало:
Чрезмерный максимальный эффективный размер базы данных (mysql). (Общее пространство, требуемое для изображений, превышает всех других на по крайней мере 2 порядки величины).
Файлы изображений теряют свой "fileness". Никакие размеры дат и т.д., если не сохранено (избыточно) как даты (которые требуют кода для управления).
Произвольные последовательности байта не обрабатывают приятно все время, или для устройства хранения данных или для управления.
"Мы никогда не должны будем получать доступ к изображениям внешне", опасное предположение.
Хрупкость. Поскольку целое расположение является неестественным и раздражительным, и Вы не знаете, где оно укусит затем (способствующий антиосуществлять рефакторинг менталитету).
преимущества? Ни один, о чем я могу думать, кроме него, возможно, не был путем наименьшего сопротивления в то время.
Я думаю, что это зависит от приложения Ваше здание. Если Вы создаете систему CMS, и использование данных идет, к изображениям на дисплее в веб-браузере, могло бы иметь смысл сохранять изображения на диск в противоположность тому, чтобы быть помещенным в базу данных. Хотя честно я сделал бы обоих, которые могли позволить добавлять сервер к ферме, не имея необходимость копировать файлы повсеместно.
Другой вариант использования мог бы быть сложным объектом, таким как рабочий процесс или даже бизнес-объект с большим количеством межзависимостей. Вы могли сериализировать оба из них в двоичный или основанный на тексте формат и сохранить их в DB. Тогда Вы извлекаете пользу из DB: АТОМАРНЫЙ, Резервные копии, и т.д.
я не думаю, что люди должны использовать select *
запросы во-первых. То, что Вы делаете, обеспечивают два способа получить данные, возвраты методов сводная информация, второе возвратило бы блоб. Я не могу вообразить, почему необходимо было бы возвратить тысячи изображений внезапно.
Мы храним вложения в нашей системе, и Вы не можете изменить вложение, таким образом, я думаю, что мы находимся на той же странице, w/data, который "будет сохранен и никогда не изменяться". Мы конкретно решили не для хранения его в базе данных. Мы сделали это по двум причинам, простоте, и время резервного копирования/восстановления.
Простота сначала: В нашем случае эти вложения загружаются от браузера конечного пользователя, и более просто просто записать им в каталог (на сервере БД), чем он должен тогда передать их потоком вниз канал SQL. Существует запись их в DB, но DB просто содержит метаинформацию о вложении и название файла на диске (гуид в нашем случае)
На стороне резервного копирования/восстановления: Эти блобы, вероятно, станут одной из самых больших частей Вашей базы данных. Каждый раз, когда Вы выполняете полное резервное копирование, Вы будете копировать эти биты много раз, даже при том, что Вы знаете, тогда никогда не может изменяться. Нам просто казалось намного более простым иметь (намного) меньшие резервные копии и сделать xcopy каталога вложения к вторичному серверу как резервное копирование.
Разве это не точно, какие СВЕЧИ или CLOBs или.... были разработаны?
Мы использовали CLOBs для хранения большого шифрования транзакций по карте кредитной карты для главной системы авиакомпании.
Потребление памяти является Вашим самым великим преступником все же.
аплодисменты HTH
,
Некоторая база данных (например, Postgresql) автоматически сжимает поля, возможно, это быстрее при чтении их непосредственно из дб. И также, программа может считать все поля и изображение в одном налете.
Проблема производительности здесь как адрес выше, таким образом, я не повторю его. Но я думаю хороший совет, если Вы храните вещи, которые будут переданы потоком много (такие как изображения/документы на веб-сайте), должен создать в кэширующейся системе.
этим я имею в виду, хранят все данные в Вашей базе данных, но когда кто-то запрашивает, чтобы файл, проверьте, существует ли это на диске (на основе известного имени файла во временной папке), в противном случае захватите его от DB и запишите его в папку и затем поток это пользователю. Для следующего запроса в тот же файл, так как это существует на диске, это может быть подано оттуда, не поражая DB. Но если необходимо удалить эти файлы (или веб-сервер идет уничтоженный!), это не имеет значения, поскольку они будут восстановлены снова от DB, поскольку люди запрашивают их. Это должно быть намного более быстро, чем обслуживание каждого запроса на тот же файл от DB.
Рассматривая вопрос с точки зрения принципов, реляционная база данных (в основном) существует для хранения структурированных данных. Если вы не можете сделать условие запроса или соединение на элементе данных, то, вероятно, ему не место в базе данных. Я не вижу, чтобы BLOB изображения использовался в предложении WHERE, поэтому я бы сказал, что он не должен находиться в базе данных. CLOB, с другой стороны, может использоваться в запросах.