Каков наилучший способ перебора и обработки всей таблицы из базы данных? - PullRequest
1 голос
/ 30 октября 2011

В моей базе данных есть таблица с именем Token, представляющая токенизированные тексты.

Каждая строка имеет такие атрибуты, как текстовый блок, предложение и положение (для идентификации текста, из которого получен токен) и логические поля, такие как текст, категория, тип диаграммы и т. Д.

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

Каков наилучший способ сделать это? С помощью SQL-запросов можно найти шаблоны или выполнить итерацию по всем токенам в таблице. Я думаю, что запросы будут очень сложными и, возможно, итерация в виде списка будет более простой, но я не знаю, какой путь (например, получение в список Java или использование языка, который я могу перебирать и делать изменения прямо в базе данных).

Чтобы этот вопрос не был закрыт, я хочу знать, каков наиболее рекомендуемый способ сделать это? Я использую Java, но если другой язык лучше, нет проблем, я думаю, мне понадобится использовать R для статистического исчисления.

Редактировать: Таблица большая, миллионы строк, полная загрузка в память невозможна.

Ответы [ 5 ]

3 голосов
/ 30 октября 2011

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

Имейте в виду, что каждый раз, когда вы пытаетесь объединить две строки в одну, вы будете удалять данные. В худшем случае вы можете объединить ВСЕ свои ряды в один. Действуйте с осторожностью!

2 голосов
/ 30 октября 2011

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

Если размер становится больше, чем "что вписывается в редактор ", вам понадобится какая-то база данных.Это может быть или не быть базой данных SQL.Но есть и часть кода: если вы хотите выполнять нетривиальные операции с данными, вам может понадобиться настоящий язык программирования (может быть что угодно: C, Java, Python. Что угодно).В этом случае связь с базой данных станет узким местом: вам нужно генерировать запросы, которые дают результаты, которые помещаются в память прикладной программы.SQL достаточно мощный, чтобы представлять и хранить N-граммы и выполнять некоторые вычисления на них, но это примерно так, как вы собираетесь получить.В любом случае база данных должна быть полностью нормализована, и это сделает ее более трудной для понимания не-администраторами баз данных.

Мой собственный игрушечный проект http://sourceforge.net/projects/wakkerbot/ использовал гибридный подход:

  • данные были получены сканером Python
  • корпус был сохранен как есть в базе данных
  • фактический (модифицированный MegaHal) марковский код хранит свою собственную версиюкорпуса в (двоичном) плоском файле, содержащем словарь, N-граммы и связанные с ними коэффициенты.
  • обучение и генерация текста осуществляется с помощью высокооптимизированной программы C
  • выводбыл подобран другим скриптом Python и передан цели.

[в другой жизни я бы, вероятно, сделал бы еще некоторую нормализацию и сохранил бы N-граммы или деревья в базе данных.Это может привести к падению производительности до нескольких сгенерированных предложений в секунду.Сейчас оно составляет около 4000 / сек.]

Мне кажется, что то, что вы хотите, больше похоже на «лингвистический верстак», чем на программу, которая эффективно выполняет только одну задачу (например, wakkerbot).В любом случае вам нужно немного нормализовать: сохраняйте токены как {tokennumber, tokentext} и обращайтесь к ним только по номеру.По сути, текст - это просто таблица (или массив), содержащая набор номеров токенов.N-грамм - это просто пара чисел + соответствующие коэффициенты.

2 голосов
/ 30 октября 2011

Это не самый оптимизированный метод, но он позволяет легко писать код.

  1. написать класс сущностей, представляющий строку в вашей таблице.

  2. написать фабричный метод, который позволяет вам получить объект сущности с заданным идентификатором строки, т.е. метод, который создает объект класса сущности со значениями из указанной строки.*

  3. написать методы, которые удаляют и вставляют данный объект строки в таблицу.

  4. записывают метод подсчета строк.

  5. Теперь вы можете попробовать перебрать вашу таблицу, используя ваш Java-код.помните, что если вы объединяете две строки, вам нужно правильно настроить следующий индекс.

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

Концепция очень похожа или идентична ORM (Object Relational Mapping).Если вы знаете, как использовать hibernate или другие ORM, попробуйте эти библиотеки.

1 голос
/ 30 октября 2011

Звучит так, будто вы разрабатываете систему поиска текста.Сначала вы должны увидеть, подходит ли вам система полнотекстового поиска pgsql.

Если вы делаете это без полнотекстового поиска, загрузка pl в pgsql и обучение его управлению, вероятно, будет самым быстрым и наиболее эффективным решением.Это позволит вам поместить всю эту работу в несколько хорошо продуманных строк R и делать все это в БД, где доступ к данным наиболее близок.единственное время, чтобы избежать такого плана, - это когда ОЧЕНЬ тяжело будет работать сервер базы данных, как, например, удержание набора данных в памяти и запуск одного ядра процессора через него.Тогда это нормально делать на стороне приложения.

Независимо от того, используете ли вы pl / R или нет, обращаетесь к большим наборам данных в курсоре, это, безусловно, самый эффективный способ получить либо одно, либо меньшее подмножество строк.Если вы делаете это с помощью оператора select с предложением where для каждой вещи, которую вы хотите обработать, вам не нужно хранить все эти строки в памяти сразу.Вы можете захватывать и отбрасывать части наборов результатов, выполняя такие действия, как подсчет средних значений и т. Д.

Подумайте о масштабе здесь.Если бы у вас была база данных объемом 5 ТБ, как бы вы получили к ней доступ, чтобы сделать это быстрее всего?Плохое решение для масштабирования вернется, чтобы укусить вас, даже если он имеет доступ только к 1% набора данных.И если вы уже сегодня начинаете работу с довольно большим набором данных, со временем оно только ухудшится.

pl / R http://www.joeconway.com/plr/

1 голос
/ 30 октября 2011

IMO было бы проще и, скорее всего, быстрее загружать все в Java и выполнять там свои операции, чтобы избежать постоянного повторного запроса к БД.статистика тоже;Я не откажусь от этого, пока вы не убедитесь, что то, что вам нужно, недоступно (или слишком медленно).

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