Файл против базы данных для эффективности хранения в приложении чата - PullRequest
4 голосов
/ 11 июня 2011

Я работаю над простой надстройкой чата AJAX для моего PHP-приложения, чтобы обеспечить поддержку в реальном времени для моих пользователей. В настоящее время я использую базу данных MySQL, хранящую текст, метку времени и user_id человека, который в чате. Я задумался о том, как оптимизировать свой чат, и подумал об устранении необходимости в базе данных SQL.

Мой вопрос, было бы более эффективно использовать fwrite() для добавления дополнительных данных в файл PHP для хранения той же информации, а не для создания соединения SQL для получения новых сообщений в чате? Я знаю, как бы это сделать эффективно, я просто пытаюсь выяснить, какой путь будет более эффективным.

Я тоже немного посмотрел на SQLite; это будет лучшей альтернативой, чем использование базы данных MySQL?

Ответы [ 6 ]

6 голосов
/ 11 июня 2011

Системы управления базами данных (СУБД) существуют, потому что это не так просто, как кажется, для правильного хранения и доступа к данным.

Хранение данных в файле подразумевает проблемы параллелизма доступа.Когда файл станет больше, вам придется столкнуться с важным использованием памяти или написать много кода, чтобы загрузить именно то, что вам нужно.Также будет довольно сложно выполнять базовые операции, такие как фильтрация (предложение SQL WHERE) или обновление строки.Кстати, изменение структуры данных обещает быть подверженным ошибкам.Проще говоря: вам придется написать много кода и столкнуться с множеством ошибок.

IMO, без использования какой-либо СУБД воссоздает колесо.Однако важно выбрать правильный.

2 голосов
/ 17 октября 2015

Я брошу сюда свою шляпу, даже если это старый вопрос.По скорости, надежности и простоте использования БД является очевидным легким выбором ... С одним серьезным предостережением, которое пропускают многие люди, а именно с большинством общих хостов (наиболее распространенная форма веб-хостинга) разрешено только 15 илиТаким образом, соединения сразу, даже VPS обычно разрешают только 100-200, а выделенные - 500 или более.Это означает, что если у вас есть (n) пользователей, объединяющих пулы каждые (s) секунд, эти соединения будут быстро израсходованы, даже быстрее, если вы также используете какой-либо CMS.Находясь в процессе разработки собственного кода чата на VPS, я тоже сам сталкиваюсь с этими проблемами.

Пока мой метод был таким:

  • Обязательно пройдитеПеременная lastMessageReceived для ограничения ответа.
  • Если общедоступный чат передает фильтр отметок времени, а также приведенный выше
  • , если это вообще возможно, использовать механизм кэширования БД, такой как MySQLnd, с включенным кэшированием запросов и TTL.установите любую скорость пулирования.
  • Не сходите с ума от скорости пулирования. 1-2-секундные интервалы могут показаться аккуратными и быстрыми, но это убьет количество ваших соединений.Снижение этого до 5 с или даже больше не будет иметь большого значения, и пользователи, вероятно, не заметят, и нагрузка на ваш сервер будет намного меньше.Даже учитывайте переменную частоту пула, которая повышается во время высокой нагрузки.
  • Напишите ваш ajax, чтобы использовать тайм-аут вместо интервала для его пула, и поместите вызов timeout в обратный вызов ajax success, это предотвратит суммирование запросов во времяpeak ussage.
  • И самый большой, если вы используете общий чат с большим количеством пользователей, напишите свой собственный код для кеширования SQL-запроса в файл json, затем отправьте его в ajax-запросы и напишите некоторый пользовательский код TTL.Чтобы проверить его возраст и повторно заполнить его по мере необходимости во время запросов, CRON был бы здесь полезен, если ваш хост позволяет.Проверка возраста файла и перенаправление на него AJAX-запроса - это функция более высокого уровня с минимальными нагрузками на сервер, особенно по сравнению с запросами к БД.И не анализируйте файл в PHP, пытаясь отфильтровать старые сообщения, сохраните файл с первым сообщением в имени файла, например chat_243.json, и сохраните его как уже отформатированный json, а затем просто подайте весь файл, если поступит запросв php с lastMessageReceived = 243.Так как это создаст несколько файлов, вам понадобится функция для очистки файлов старше (м) минут, но это также легкая работа для сервера.

Существуют также такие варианты, как разработанные механизмы БДдля чата и сокетов (node.js), но для них требуется больше настроек сервера, чем позволяют обычные учетные записи хостинга, для моих целей я писал свой чат, имея в виду, что в какой-то момент он может быть развернут на общем сервере.

Вот код, который я использую в настоящее время, и он в значительной степени позволил мне расширить свой чат до неограниченного количества соединений (в пределах пропускной способности серверов)

$cacheFile = 'cache/chat_'.$_GET['last'].'.json';

if (file_exists($cacheFile) && filemtime($cacheFile) + QUERY_REFRESH_RATE > time())
{
    readfile($cacheFile);
} else {
    require_once("../../../../wp-load.php");
    $timestampMin = gmdate("Y-m-d H:i:s", (time() - 7200));

    $sql= "/*qc=on*/" . "SELECT * FROM ". DB_TABLE ."chat_posts WHERE ID > ". $_GET['last'] . " AND timestamp > '".$timestampMin."' ORDER BY ID;";
    $posts = $wpdb->get_results($sql);

    $json = json_encode($posts);
    echo $json;
    file_put_contents($cacheFile,$json);
}
0 голосов
/ 05 июля 2019

У меня было подобное соображение, и я написал это общее, простое и высокопроизводительное решение, которое вам может понравиться Rocket-store

Включите один файл иВы можете начать вставлять записи прямо сейчас.

У него есть три основных метода: put , get и delete (и некоторые специальные методы и настройки параметров)

Пример:

// collection/table = "cars", key = "Mercedes"
$rs->post("cars", "Mercedes-Benz GT R", ["owner" => "Lisa Simpson",reg: "N3RD"]);

// Get all records from "cars" collection
$result = $rs->get("cars", "Mercedes*");

// Delete records in collection "cars" where keys match "*cede*"
$rs->delete("cars", ""*cede*"");

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

Это легко в 100 раз быстрее, чем реляционная база данных, на вставках.Обычно 40 000 вставок / сек.Вам не нужно ничего устанавливать, кроме этого включаемого файла.

Вы получаете простые последовательности, автоинкремент и другие незначительные удобства, но об этом.Ничего фантастического.

Мне это очень нравится, когда мне нужны простые решения для хранения данных, но я также очень предвзят;)

0 голосов
/ 12 июня 2011

Так как другие рассматривали MySQL против Text, я бы хотел дать вам альтернативу.

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

Вы также можете использовать что-то вроде Node.JS , чтобы связать все это вместе.

0 голосов
/ 12 июня 2011

Я бы придерживался MySQL, так как он больше подходит для множественного доступа из веб-приложения, чем простой файл.

Во-первых, используйте постоянные соединения.

При его использовании я бы предложил использовать PDO, если вы еще этого не сделали. (Опция PDO для постоянных соединений: PDO :: ATTR_PERSISTENT => true)

Примечание: настройка по умолчанию в PHP - просто эмулировать подготовленный оператор. Вы хотите, чтобы это был TRUE подготовленный оператор, поэтому установите PDO :: ATTR_EMULATE_PREPARES в 0. (http://bugs.php.net/bug.php?id=54638)

Также: Подготовленные операторы не будут использовать кэш MySQL в версиях до 5.1.17 и не будут кэшировать подготовленные операторы до 5.1.21, поэтому убедитесь, что у вас установлена ​​последняя версия MySQL.

PDO обеспечивает больше, чем потенциальное повышение производительности. Вы должны посмотреть, если вы еще не сделали. Подробнее о PDO здесь: http://ca2.php.net/manual/en/book.pdo.php

0 голосов
/ 11 июня 2011

Если вы удалите или заархивируете старые разговоры, MySQL будет хорошим выбором.Не забывайте размещать индексы по дате и пользователю или идентификатору сеанса, чтобы их можно было быстро получить.

...