Jump to content
  • 0

Базы данных или файлы?


Maslakoff
 Share

Question

Базы данных или файлы?

Перед тем как сесть писать новый скрипт вы точно хоть раз, но задумывались ? писать его с использованием баз данных(БД) или все так же, как привыкли ? на файлах?

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

Как мы работаем с файлами?

Заранее условимся, что функция file() это упрощение того, что описано ниже?

Работать с файлами легко. Это делается примерно в 3 этапа:

1. Открыл файл

2. Считал всю(или часть) информацию

3. Закрыл файл

Теперь(с точки зрения скрипта) мы имеем просто кучу символов разделенных переводом строки.

Павел|pavel@mail.ru|43284343|Привед, классный у тебя сайтик?!

Александра|alex-sashka@gmail.com|384323|Приветик, кот?нок, суперовый сайтик!

Евгений|gg_potstolom@pochta.ru|11132342|ЫЫЫ... Здарова, чертяко!

Делаем разбиение по строкам и получаем уже массив строк файла.

1. Павел|pavel@mail.ru|43284343|Привед, классный у тебя сайтик?!

2. Александра|alex-sashka@gmail.com|384323|Приветик, кот?нок, суперовый сайтик!

3. Евгений|gg_potstolom@pochta.ru|11132342|ЫЫЫ... Здарова, чертяко!

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

1.

a) Павел

б) pavel@mail.ru

в) 43284343

г) Привед, классный у тебя сайтик?!

2.

а) Александра

б) alex-sashka@gmail.com

в) 384323

г) Приветик, кот?нок, суперовый сайтик!

3.

а) Евгений

б) gg_potstolom@pochta.ru

в) 11132342

г) ЫЫЫ... Здарова, чертяко!

a) ? имя посетителя

:) ? адрес почтового ящика

c) ? номер ICQ

d) ? сообщение

Теперь перебирая каждую строку, разбиваем е? на ?подстроки?. Зная позицию каждой подстроки, мы можем сказать где находиться имя посетителя, а где его сообщение.

Дело за малым ? вывести все красиво на страницу.

Чтобы добавить сообщение нам нужно:

1. Открыть файл для добавления

2. Записать в конец данные

3. Закрыть файл

Еще нам нужно следить за тем, чтобы в файл попали данные без специального, условленного символа-разделителя ? ?|? и данные без ?перевода строки?!

Итак, мы формируем строчку вида:

?имя пользователя?|?адрес почты?|?номер ICQ?|?сообщение?

Сохраняем в файл и радуемся жизни!

Как выглядит работа с файлами в Php-коде:

<html>

<head>
<title>Пример гостевой книги на файлах</title>
</head>

<body>

<form action="?action=add_post" method="post">
<p>* Имя посетителя:</p>
<p><input name="name" type="text"></p>
<p>* Электронная почта:</p>
<p><input name="email" type="text"></p>
<p>ICQ:</p>
<p><input name="icq" type="text"></p>
<p>* Сообщение:</p>
<p><textarea name="message" rows=5 cols=20></textarea></p>
<p><input type="submit" value="Добавить сообщение"></p>
</form>

<?php

if( @$_GET['action'] == "add_post" ) // Если мы хотим добавить сообщение
{
if( !empty($_POST['name']) && !empty($_POST['email']) && !empty($_POST['message']) ) // Проверяем на наличие обязательных данных
{
// Удаляем запрещенные символы
$name = str_replace('|', '!', htmlspecialchars(strip_tags($_POST['name'])));
$email = str_replace('|', '!', htmlspecialchars(strip_tags($_POST['email'])));
$icq = str_replace('|', '!', htmlspecialchars(strip_tags($_POST['icq'])));
$message = str_replace('|', '!', htmlspecialchars(strip_tags($_POST['message'])));

$fp = @fopen ("guestbook.txt", "a+"); // Открываем файл для добавления в конец

if( @fwrite ($fp, "$name|$email|$icq|$messagen") ) // Проверяем на успешность записи в файл
{
print "<p style='color:green;'>Сообщение успешно добавлено!</p>";
}

@fclose ($fp); // Закрываем файл
}
else
{
print "<p style='color:red;'>Введены не все данные!</p>";
}
}

?>

<hr>

<?php

$fp = @fopen ("guestbook.txt", "r"); // Открываем файл для чтения
$gb_content = @fread($fp, filesize("guestbook.txt")); // Читаем все символы из файла
@fclose ($fp); // Закрываем

if( !empty($gb_content) )
{

$gb_content = split("n", $gb_content); // Разбили на строки

for( $i=0; $i<count($gb_content)-1; $i++ )
{
list( $gb_name, $gb_email, $gb_icq, $gb_message ) = explode('|', $gb_content[$i]); // Разбиваем на подстроки и получаем соответствующие данные

// Выводим сообщение
print "<p style='color:blue;'><a href='mailto:$gb_email'>$gb_name</a> ICQ: $gb_icq</p>n";
print "<p>$gb_message</p>n";
print "

n";
}
}
else
{
print "Гостевая, увы, пуста!";
}

?>

</body>

</html>

Как мы работаем с базой данных(БД)?

Что бы работать с БД нам необходим хостинг с поддержкой хотя бы MySQL. В этом конечно виден явный минус БД, но все по порядку?

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

БД работает почти точно так же как и файлы:

1. Открываем БД

2. Читаем/записываем данные

3. Закрываем

Главным отличием является то, что мы получаем не кучу символов, а уже упорядоченный массив данных! То есть мы не морочим себе голову вопросами ? ?А какой поставить разделитель??, ?Как разбить на подстроки??, ?Каким по порядку идет поле, к примеру, номер ICQ??, ?Как отфильтровать входные данные на предмет перевода строки??.

Вс? это уже предусмотрено базой данных?

Созда?м БД, в ней таблицу guestbook с соответствующими полями:

1) ? имя посетителя

2) ? адрес почтового ящика

3) ? номер ICQ

4) ? сообщение

Заполняем данными? Получаем:

 +——-+———+——-+——————-+
| Имя | Email | ICQ | Сообщение |
+——-+———+——-+——————-+
| Павел | pav... | 123232| Привет.. |
+——-+———+——-+——————-+
| Лелик | lelik.. | 23232 | Здароф.. |
+——-+———+——-+——————-+
......................................

Осталось только соедениться с БД и сделать запрос на выборку данных:

SELECT * FROM guestbook

Слово SELECT означает операцию ?чтения? данных. Символ ?*? ? что нам нужны поля: ?имя посетителя?, и ?почтовый адрес?, и ?номер ICQ?, и ?сообщение?, В общем все данные. FROM guestbook ? означает, что данные мы хотим прочитать из таблицы ?guestbook?. Грубо говоря таблица ? это и есть файл.

Чтобы записать данные в БД просто выполняем запрос:

INSERT INTO guestbook(?имя посетителя?, ?адрес почтового ящика?, ?номер ICQ?, ?сообщение? ) VALUES (?Иван?, ?ivan@sobaka.ru?, ?123456?, ?Я Иван! Повелитель гостевых книг!?)

INSERT ? говорит нам, что это операция вставки, ?guestbook? ? таблица для вставки, дальше перечислены поля в которые необходимо записать данные, VALUES ? означает что дальше идет перечисление самих данных через запятую.

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

Как выглядит работа с БД в Php-коде:

Прежде чем опробовать код вам нужно создать БД с названием guestbook. В этой БД создать таблицу guestbook с полями id, name, email, icq, message. Или просто выполнить SQL запрос:

CREATE TABLE `guestbook` (
`id` INT NOT NULL AUTO_INCREMENT ,
`name` VARCHAR( 50 ) NOT NULL ,
`email` VARCHAR( 70 ) NOT NULL ,
`icq` VARCHAR( 10 ) NOT NULL ,
`message` TEXT NOT NULL ,
PRIMARY KEY ( `id` )
);

Код гостевой:

<html>

<head>
<title>Пример гостевой книги с использованием БД</title>
</head>

<body>

<form action="?action=add_post" method="post">
<p>* Имя посетителя:</p>
<p><input name="name" type="text"></p>
<p>* Электронная почта:</p>
<p><input name="email" type="text"></p>
<p>ICQ:</p>
<p><input name="icq" type="text"></p>
<p>* Сообщение:</p>
<p><textarea name="message" rows=5 cols=20></textarea></p>
<p><input type="submit" value="Добавить сообщение"></p>
</form>

<?php

$db = mysql_connect('localhost', 'root', ''); // Подключаемся к базе данных

mysql_select_db('guestbook', $db); // Выбираем таблицу guestbook с которой будем работать

if( @$_GET['action'] == "add_post" ) // Если мы хотим добавить сообщение
{
if( !empty($_POST['name']) && !empty($_POST['email']) && !empty($_POST['message']) ) // Проверяем на наличие обязательных данных
{
// Удаляем запрещенные символы
$name = htmlspecialchars(strip_tags($_POST['name']));
$email = htmlspecialchars(strip_tags($_POST['email']));
$icq = htmlspecialchars(strip_tags($_POST['icq']));
$message = htmlspecialchars(strip_tags($_POST['message']));

// Формируем запрос для добавления
$query = "INSERT INTO guestbook(name, email, icq, message) VALUES ('$name', '$email', '$icq', '$message')";

$result = mysql_query( $query, $db ); // Выполняем запрос

if( $mysql_error = mysql_error( $db ) ) // Если возникли какието ошибки, то выводим их
{
print $mysql_error;
}
else
{
print "<p style='color:green;'>Сообщение успешно добавлено!</p>";
}
}
else
{
print "<p style='color:red;'>Введены не все данные!</p>";
}
}

?>

<hr>

<?php

// Формируем запрос на получение данных
$query = "SELECT * FROM guestbook";

$result = mysql_query( $query, $db ); // Выполняем запрос

if( mysql_num_rows( $result ) > 0 ) // Проверяем колличество полученных строк
{
while( $gb_content = mysql_fetch_array( $result ) ) // Читаем по-очереди каждую строку
{
// Выводим сообщение
print "<p style='color:blue;'><a href='mailto:$gb_content[email]'>$gb_content[name]</a> ICQ: $gb_content[icq]</p>n";
print "<p>$gb_content[message]</p>n";
print "

n";
}
}
else
{
print "Гостевая, увы, пуста!";
}

?>

</body>

</html>

Про безопасность

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

Ситуация с файлами обстоит плачевна? Иногда забывают ?закрывать? файлы от чтения из вне и вс? содержимое гостевой, а может и списка зарегистрированных пользователей с паролями и почтовыми адресами попадает в руки к злоумышленникам.

Забывают экранировать ввод нового сообщения и вся информация в гостевой превращается в кашу?

Базы данных тоже не лишены недостатков. Если программист не проверяет передаваемые из формы данные на правильность, то злоумышленник спокойно может прочитать, к примеру, список всех пользователей, или зайти под другим ником. Данный вид хака называется SQL Injection.

Работы в улучшении защиты уже ведутся давно. Например, в библиотеке DbSimple от DKLab это решено с помощью placeholder-ов.

Выводы

Я, например, работаю с БД, выбирая тем самым безопасность и структурированность моих данных, но и не отрицаю использование файлов. Например, есть хорошие способы хранения данных в файлах:

1. Использование функций serialize() и unserialize()

2. Хранение в ini-файлах

Иногда приходиться пользоваться и такими способами.

Список литературы для углубленного изучения

1. Основы работы с MySQL в PHP

2. "Работа с MySQL в PHP: с чего начать?"

3. Работа с MySQL в PHP: подробно (PHP, MySQL, веб-программирование)

4. Обучающая статья от ведущего разработчика phpMyAdmin Марка Делисла

5. Работа с MySQL: Подробнее(Как формировать запросы)

6. Библиотека DbSimple от DKLab

Статьи не сильно объемные и не займут много времени, но зато ваш exp значительно возрастет.

Для тех, кто привык читать документы MS Word.

  • Like 1
Link to comment
Share on other sites

Recommended Posts

  • 0
Павел|pavel@mail.ru|43284343|Привед, классный у тебя сайтик?!

Александра|alex-sashka@gmail.com|384323|Приветик, кот?нок, суперовый сайтик!

Евгений|gg_potstolom@pochta.ru|11132342|ЫЫЫ... Здарова, чертяко!

Никогда не храните информацию подобным образом.

Берите пример с БД, резервируйте в файле место под соответствующие типы данных,

потом соответственно типу их вытаскивайте. Разделители не понадобятся, скорость чтения увеличится и память сэкономите.

Работы в улучшении защиты уже ведутся давно. Например, в библиотеке DbSimple от DKLab это решено с помощью placeholder-ов

Placeholder есть в любых orm (propel, doctrine и пр.), и бд об?рток в фреймворках (zf, limb и пр.). И это всего лишь вершина айсберга :)

Link to comment
Share on other sites

  • 0

ммм... я свои 5 копеек выложу...

начнем с того, что обсуждение изначально лишено смысла... db - не файлы? кто вам сказал такую глупость? эти самые файлы и есть... более того, при корректном построении скриптов вполне можно на файлах построить вполне приличный движок чтения/записи/сортировки информации...

Берите пример с БД, резервируйте в файле место под соответствующие типы данных,

вполне разумное замечание... вот только не всегда уместное...

в примере показанном тут

$file = file('...');

for(...) $file[$i] = explode('|',$file[$i]);

гораздо практичнее и не потребуется множественных операций, выделение места разумно и необходимо ТОЛЬКО при разношерстных данных, когда разделитель не может быть установлен, либо данные строк имеют громадное различие объема информации

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

На самом деле, по сути вопроса, ответ прост - кому что больше нравится :)

Link to comment
Share on other sites

  • 0

NJSmith, в универе, в курсе лекций по БД и по Структурам баз данных нам это уже объяснялось.

Статья для новичков. Для них БД и файлы ? два разных понятия. И зачем изобретать колесо, если можно уже кататься на готовом велосипеде?

Link to comment
Share on other sites

  • 0

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

Link to comment
Share on other sites

  • 0

нормальный мануальчик, хотя некоторые фразы улыбнули - например:

Что бы работать с БД нам необходим хостинг с поддержкой хотя бы MySQL. В этом конечно виден явный минус БД, но все по порядку?

ну да, а для работы с файлами необходим компьютер с монитором и даже клавиатура ;)

по поводу безопасности - наверное все-таки файлы более безопасны, хотя под регистр глобал = офф уже давно никто не пишет

имхо, основной критерий - скорость

при небольших обьемах выигрывают файлы, а когда данных много и высока посещаемость - однозначно база

Link to comment
Share on other sites

  • 0
нормальный мануальчик, хотя некоторые фразы улыбнули - например:
Что бы работать с БД нам необходим хостинг с поддержкой хотя бы MySQL. В этом конечно виден явный минус БД, но все по порядку?

ну да, а для работы с файлами необходим компьютер с монитором и даже клавиатура :(

по поводу безопасности - наверное все-таки файлы более безопасны, хотя под регистр глобал = офф уже давно никто не пишет

имхо, основной критерий - скорость

при небольших обьемах выигрывают файлы, а когда данных много и высока посещаемость - однозначно база

:( для юзверей эти фразы абсолютно нормальны, что такое MySQL знают в реале не многие, как оно устроено, где и как лежат базы и таблицы... это все лирика, так что фраза "необходим хост с поддержкой MySQL" - вполне приличная фраза, если ты не сисадмин со своим серваком с подцепленным хостом и прочими прелестями

"по поводу безопасности - наверное все-таки файлы более безопасны, хотя под регистр глобал = офф уже давно никто не пишет"

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

не думаю, что твой синтаксис будет лучше или безопаснее MySQL'ного

и далее - скорость не есть решающий фактор, решающий фактор ВСЕГДА базопасность, и если это для сайта не так - то это не профессиональный сайт, а сваянная на коленке самоделка.

звиняйте все, если грубовато ответил, но :xz: это мое скромное О

Link to comment
Share on other sites

  • 0

Все это прекрасно, но меня всегда мучает один вопрос:

Представьте ситуацию, когда 2 (или более) пользователей отправляют сообщение одновременно. Ситуация практически невозможная, возможна лишь теоретически (или по теории вероятности). Тем не менее 2 (или более) запроса на запись в файл прошли одновременно, что же будет с записями? Вопрос корявости вашего скрипта, который запущен 2-мя (или более) пользователями.

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

Конечно это сугубо мое мнение (ИМХО). С файлами мороки много.;)

Link to comment
Share on other sites

  • 0

Да легко такое произойти может.

Даже если запросы отправлены не одновременно, то предыдущий сеанс записи в файлы может ещ? не закончится перед тем, как начн?тся второй сеанс.

Link to comment
Share on other sites

  • 0

Ничего подобного... Запросы на один файл легко могут быть отправлены одновременно.

Мы тестировали чат, который был на файлах, запуская ботов.. Так вот 200 ботов одновременно постят сообщения...

Решается это использованием flock. И когда файл залочен на добавление, то другому пользователю просто выдается сообщение о невозможности добавления, что не редко раздражает. И это решаемо функцией sleep.

БД предлагает куда более продуманную систему блокирования таблиц. Можно блокировать только отдельные таблицы, даже просто отдельные записи.. Тоесть база всеравно остается открыта для добавления новых данных. Причем, существует очередь... Тоесть если 2 записи добавляются одновремено, то они выстраиваются в очередь: вторая ждет пока завершится процесс добавления первой.

Link to comment
Share on other sites

  • 0

Существует альтернатива — SQLite(расширение к PHP). Те же самые БД, но хранящиеся в файлах.

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

Link to comment
Share on other sites

  • 0

лично мне приходится работать и с файлами и с БД,

правда с файлами, в которых нужно изменять данные (data.txt к флэшу к примеру).

само ядро для такой работы с файлом весит около 24КБ (тупо функции по работе и изменению), и при изменении данных в файле грузит локальную машину ой ой ой как...

если же работать с БД то весить ядро работы будет около 4-5КБ и работает гораздо быстрее...

так что мое мнение - ТОЛЬКО БД для хранения данных.

Link to comment
Share on other sites

  • 0

Скажите пожалуйста, какие базы данных вы использзуете при программировании на PHP. Особенно интересно, используете ли не реляционные базы данных и что о них думаете? я нашёл одну XML базу данных - оказалось очень удобно, гибко и симпатично... неужели я один такой

Link to comment
Share on other sites

  • 0

А у тебя в проекте какие запросы будут чаще остальных?

смотри характеристики баз данных.

например(вроде) SELECT быстрее выполняется на постгрее, а инсерт у sqllite.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy