[…], поэтому я использую составной ключ, чтобы убедиться, что комбинация name и group_id не может использоваться 2 раза.
blockquote>Вы описываете необходимость ограничения; это не должно быть ключом вообще. При определении таблицы вы можете указать ограничение, что несколько полей должны быть уникальными вместе:
CREATE TABLE tag ( name varchar(50), group_id int, UNIQUE (name, group_id) );
Таким образом, вы получите СУБД, обеспечивающую для этих столбцов уникальную пару значений в каждой записи, не подразумевая, что являются ключом для поиска.
Итак, вы можете назначить любой первичный ключ, который вам нравится. Поскольку вы хотите, чтобы поле
id
было первичным ключом, сделайте это:CREATE TABLE tag ( name varchar(50), group_id int, id serial NOT NULL, UNIQUE (name, group_id), PRIMARY KEY (id) );
Настоящий паук - это много работы
Написание паука для всей WWW - довольно сложная задача - вы должны позаботиться о многих «мелкие детали», такие как:
Это большая работа. Но если ваша цель скромнее, чем читать весь WWW, вы можете пропустить некоторые части. Если вы просто хотите загрузить копию вики и т. Д., Переходите к спецификациям wget.
Примечание: если вы не верите, что это так много работы, вы можете прочитать, как Google повторно изобрел большую часть вычислительных колес (поверх базового ядра Linux) для создания хороших пауков. Даже если вы срежете много углов, это будет много работы.
Позвольте мне добавить еще несколько технических замечаний по трем пунктам
Параллельные соединения / асинхронная связь через сокеты
Вы можете запускать несколько программ-пауков в параллельных процессах или темы. Но вам нужно около 5000-10000 параллельных соединений, чтобы эффективно использовать ваше сетевое соединение. И такое количество параллельных процессов / потоков создает слишком много накладных расходов.
Лучшее решение - асинхронный ввод / вывод: обрабатывать около 1000 параллельных соединений в одном потоке, открывая сокеты в неблокирующем режиме и используя epoll или выбирая для обработки только тех соединений, которые получили данные. Начиная с ядра Linux 2.4, Linux имеет отличную поддержку масштабируемости (я также рекомендую вам изучить файлы с отображением памяти), которые постоянно улучшаются в более поздних версиях.
Примечание. Использование асинхронного ввода-вывода помогает гораздо больше, чем использование «быстрого языка»: Лучше написать процесс, управляемый epoll, для 1000 соединений, написанный на Perl, чем запускать 1000 процессов, написанных на C. Если вы все сделаете правильно, вы можете заполнить 100-мегабайтное соединение процессами, написанными на Perl.
Из исходного ответа: В Linux есть отличная поддержка масштабируемости (я также рекомендую вам изучить файлы с отображением в память), которые постоянно улучшаются в более поздних версиях.
Примечание. Использование асинхронного ввода-вывода помогает гораздо больше, чем использование «быстрого языка»: лучше написать Процесс, управляемый epoll, для 1000 соединений, написанных на Perl, чем для запуска 1000 процессов, написанных на C. Если вы все сделаете правильно, вы можете заполнить 100-мегабайтное соединение процессами, написанными на Perl.
Из исходного ответа: В Linux есть отличная поддержка масштабируемости (я также рекомендую вам изучить файлы с отображением в память), которые постоянно улучшаются в более поздних версиях.
Примечание. Использование асинхронного ввода-вывода помогает гораздо больше, чем использование «быстрого языка»: лучше написать Процесс, управляемый epoll, для 1000 соединений, написанных на Perl, чем для запуска 1000 процессов, написанных на C. Если вы все сделаете правильно, вы можете заполнить 100-мегабайтное соединение процессами, написанными на Perl.
Из исходного ответа: Если вы все сделаете правильно, вы можете насытить 100-мегабайтное соединение процессами, написанными на perl.
Из исходного ответа: Если вы все сделаете правильно, вы можете насытить 100-мегабайтное соединение процессами, написанными на perl.
Из исходного ответа: Обратной стороной этого подхода является то, что вам придется реализовать спецификацию HTTP самостоятельно в асинхронной форме (мне не известно о повторно используемой библиотеке, которая делает это). Это намного проще сделать с более простым протоколом HTTP / 1.0, чем с современным протоколом HTTP / 1.1. Вы, вероятно, в любом случае не выиграете от преимуществ HTTP / 1.1 для обычных браузеров, так что это может быть хорошим местом для экономии некоторых затрат на разработку.
Редактировать пять лет спустя: Сегодня существует множество бесплатных технологий с открытым исходным кодом, которые помогут вам в этой работе. Мне лично нравится асинхронная реализация http node.js - она избавляет вас от всей работы, упомянутой в предыдущем абзаце. Конечно, сегодня также доступно множество модулей для других компонентов, которые вам нужны в вашем пауке. Однако учтите, что качество сторонних модулей может значительно отличаться. Вы должны проверить все, что используете. [Информация об устаревании:] Недавно я написал паука, используя node.js, и обнаружил, что надежность модулей npm для обработки HTML для ссылок и извлечения данных недостаточна. Для этой работы я «передал» эту обработку процессу, написанному на другом языке программирования. Но все быстро меняется, и к тому времени, когда вы прочтете этот комментарий, эта проблема, возможно, уже уйдет в прошлое ...
Разделение работы на несколько серверов
Один компьютер не успевает за пауками всей WWW. , Вам необходимо распределить свою работу по нескольким серверам и обмениваться информацией между ними. Я предлагаю назначить каждому серверу определенные «диапазоны доменных имен»: вести центральную базу данных доменных имен со ссылкой на компьютер-паук.
Извлекать URL-адреса из полученных веб-страниц в пакеты: сортировать их по их доменным именам; удалите дубликаты и отправьте их ответственному компьютеру-пауку. На этом компьютере сохраните индекс URL-адресов, которые уже получены, и получите оставшиеся URL-адреса.
Если вы сохраняете очередь URL-адресов, ожидающих загрузки на каждом компьютере-пауке, у вас не будет узких мест в производительности. Но для реализации этого достаточно много программирования.
Прочтите стандарты
Я упомянул несколько стандартов (HTTP / 1.x, Robots.txt, Cookies). Найдите время, чтобы прочитать их и реализовать. Если вы просто будете следовать примерам известных вам сайтов, вы совершите ошибки (забудете части стандарта, не относящиеся к вашим образцам) и создадите проблемы для тех сайтов, которые используют эти дополнительные функции.
Больно читать Стандартный документ HTTP / 1.1. Но все мелкие детали были добавлены к нему, потому что кому-то действительно нужна эта маленькая деталь и теперь он ее использует.
Если вы просто будете следовать примерам известных вам сайтов, вы совершите ошибки (забудете части стандарта, не относящиеся к вашим образцам) и создадите проблемы для тех сайтов, которые используют эти дополнительные функции.Больно читать Стандартный документ HTTP / 1.1. Но все мелкие детали были добавлены к нему, потому что кому-то действительно нужна эта маленькая деталь и теперь он ее использует.
Если вы просто будете следовать примерам известных вам сайтов, вы совершите ошибки (забудете части стандарта, которые не имеют отношения к вашим образцам) и создадите проблемы для тех сайтов, которые используют эти дополнительные функции.Больно читать Стандартный документ HTTP / 1.1. Но все мелкие детали были добавлены к нему, потому что кому-то действительно нужна эта маленькая деталь и теперь он ее использует.
Я не уверен точно, на что ссылался оригинальный автор комментария, но я могу догадаться, что wget работает медленно как паук, поскольку он, кажется, использует только один поток выполнения (по крайней мере, тем, что вы показали).
«Реальные» пауки, такие как heritrix , используют много параллелизма и трюков для оптимизации их скорость сканирования, и в то же время они приятны веб-сайту, на котором они ползут. Обычно это означает ограничение количества посещений одного сайта со скоростью 1 в секунду (или около того) и одновременное сканирование нескольких сайтов.
Опять же, это всего лишь предположение, основанное на том, что я знаю о пауках в целом, и что вы разместили здесь.
К сожалению, многие из наиболее известных «настоящих» веб-пауков имеют закрытый исходный код и действительно закрытый двоичный код. Однако в wget отсутствует ряд основных методов:
Также можно использовать различные другие входные данные, такие как карты сайта и т.п. Дело в том, что wget не предназначен для просмотра всей сети, и он
Я не собираюсь вдаваться в подробности о том, как использовать паук в Интернете, я думаю, что комментарий wget касается сканирования одного веб-сайта, что по-прежнему является серьезной проблемой.
Я не знаю, сколько из них реализовано или учтено в wget, но вы можете взглянуть на httrack, чтобы понять проблемы этого задача.
Я бы хотел дать вам несколько примеров кода, но это большие задачи, и достойный паук будет около 5000 loc без сторонних библиотек .
+ Некоторые из них уже были объяснены @ yaakov-belch, поэтому я не собираюсь вводить их снова