Часть 1
17 марта 2019 г. в 11:04
Для начала я хочу вам сказать чуточку про хранение данных на сайте. Давно была изобретена такая прекрасная вещь, как СУБД (система управления базами данных). Прекрасна она по многим причинам, перечислю лишь некоторые: разработчикам сайта или любой другой программы (а сайт — это тоже программное обеспечение) не нужно придумывать свой способ хранения данных — достаточно взять готовый продукт, который гарантированно оттестирован и не содержит фатальных ошибок, и подключить к сайту.
Примеры СУБД: MySQL (и её форки), PostgreSQL, Oracle Database (почему бы и нет?), MS-SQL (?) и SQLite (прости меня Селестия. Впрочем от неё многого не ждёшь и искренне радуешься, если она что-то умеет).
Если ни одно из названий вам ничего не говорит, то забейте. Запомните только одно: у 95+% сайтов есть база данных (БД), которая чаще всего вольготно размещается на отдельном сервере. И уже её как кусочек лего программист подключает к своему сайту во время разработки.
Рассмотрим подробнее саму БД. Несмотря на сильные отличие в архитектурах и принципах построения СУБД, они во многом схожи. Все выше приведённые СУБД являются реляционными (от слова “связь”), то есть БД содержат таблицы, между которыми проведены связи.
Да-да, те таблицы похожи на знакомые вам таблицы в excel. Только таблицы в БД имеют строгую структуру: чётко фиксированный набор колонок и тип данных. Например, в поле “дата публикации главы” мы можем хранить только дату в формате DATETIME (дата и время с точностью до секунды/миллисекунды). Ещё обязателен первичный ключ — уникальный идентификатор записи, если вам будет проще понять, то “номер строчки”.
Например, вот ссылка на фанфик с идентификатором “7”:
https://ficbook.net/readfic/7
На этом, пожалуй, ликбез окончен, про язык запросов к БД (SQL) будет упомянуто ниже.
Фикбук. Недавно были добавлены метки, не буду оценивать их смысл как и существующую подборку. Моё мнение: поиск по меткам однозначно будет полезен и для авторов, и для читателей. Теперь же взглянем на техническую сторону.
В БД фикбука есть таблица “Фанфик”, в которой хранится ссылка на автора (внешний ключ, фактически идентификатор автора), название фанфика и так далее, вы все прекрасно знакомы с тем, что выводится в шапке фанфика и доступно для редактирования.
Теперь же была добавлена таблица “Тег”. В ней хранится имя тега, описание и, возможно что-то ещё, что нас сейчас не интересует.
У вас может возникнуть вопрос: а где же фанфики, у которых проставлены теги? Ответ: в промежуточной таблице, которая связывает таблицы “фанфик” и “тег” связью многие-ко-многим. То есть у одного фанфика может быть несколько тегов, так и один и тот же тег может быть поставлен многим фанфикам.
Сама структура такой таблицы выглядит примерно так:
id int — первичный ключ
fanfic_id int — ссылка на фанфик
tag_id — ссылка на тег
И теперь мы подходим к практической части статьи. Приготовьтесь копировать ссылки из текста и открывать их в новых вкладках.
Для примера возьмём тег "Регрессия возраста": https://ficbook.net/tags/102 Сколько фанфиков имеют такой тег? На 17.03.19 — 57.
>select count(*) from fanfic_tag where tag_id=102;
57
Выше SQL-запрос. Мы просим СУБД отфильтровать таблицу по условию tag_id=102 и вернуть количество получившихся записей.
Окей, не слишком много, но если отобразить на странице все 57 фанфиков, то она станет немного большой, не находите? Для этого существует пагинация — разделение результата на страницы и показ всего, допустим, 20 первых результатов:
>select * from fanfic_tag where tag_id=102 limit 0 20;
Теперь мы просим базу вернуть данные по нужному нам фильтру, но только результаты с 0 по 20 записи. Вычисление смещения в коде может выглядеть так:
begin = (p - 1) * 20
end = p * 20
Попрактикуйтесь и посчитайте результат при p=1, p=2, p=3.
https://ficbook.net/tags/102?p=1
https://ficbook.net/tags/102?p=2
https://ficbook.net/tags/102?p=3
Кто переходил по ссылкам, наверняка заметили надпись “страница 3 из 1”. Да, это баг, причём примитивный, ведь высчитать число страниц можно на коленке:
57 / 20 = 2,85 = 3
Округляем в большую сторону до целого числа.
Хотите ещё пощупать руками баги? Держите: недостаточная фильтрация входных данных.
https://ficbook.net/tags/102?p=-1
>500 — Ошибка на сервере
А если мы передадим не число, а рандомную строку?
https://ficbook.net/tags/102?p=mylittlepony
>500 — Ошибка на сервере
И на этой ноте статья резко завершается. Бай-бай!