Все очень просто наверно. Но я тупой. нужно 4 столбика. Я их сделал. 1. ID (автоинкремент) 2 NAME ( Имя товара) TEXT 3 PAGE (страница описания товара) INT 4 ABOUT (описание товара) TEXT Суть вот в чем. Будет так , что у товара несколько страниц описания. в итоге например присвоился id автоматом, затем вбил имя, номер страницы, и написал первое описание спускаюсь ниже забиваю страница №2 и пишу продолжение описания. в итоге присвоился на эту строчку свой id. Так и должно быть ?? как правильно сделать выборку и правильна ли структура ?? Может можно сделать корректней. Хочу пока работать с одной таблицей.
Структуры тут нет =) По сути ID - это id продукта, но у вас получается, что ID - это id описания =) Поле NAME должно быть уникальным, но у вас оно будет дублироваться ----------- Я предлагаю такую структуру: [sql] CREATE TABLE `products` ( `id` int(10) unsigned not null auto_increment, `name` varchar(128) not null, PRIMARY KEY (`id`), UNIQUE KEY (`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1; CREATE TABLE `pages` ( `id` int(10) unsigned not null auto_increment, `text` text, `number` int(10) unsigned not null, `product_id` int(10) unsigned not null, PRIMARY KEY (`id`), UNIQUE KEY (`number`,`product_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;[/sql] Данные: [sql]INSERT INTO `products` (`id`, `name`) VALUES ('1', 'Водка'); INSERT INTO `products` (`id`, `name`) VALUES ('2', 'Пиво'); INSERT INTO `products` (`id`, `name`) VALUES ('3', 'Сигареты'); INSERT INTO `products` (`id`, `name`) VALUES ('4', 'Хлеб'); INSERT INTO `pages` (`id`, `text`, `number`, `product_id`) VALUES ('1', 'Описание продукта \"Водка\", страница 1', '1', '1'); INSERT INTO `pages` (`id`, `text`, `number`, `product_id`) VALUES ('2', 'Описание продукта \"Водка\", страница 2', '2', '1'); INSERT INTO `pages` (`id`, `text`, `number`, `product_id`) VALUES ('3', 'Описание продукта \"Пиво\", страница 1', '1', '2'); INSERT INTO `pages` (`id`, `text`, `number`, `product_id`) VALUES ('4', 'Описание продукта \"Пиво\", страница 2', '2', '2'); INSERT INTO `pages` (`id`, `text`, `number`, `product_id`) VALUES ('5', 'Описание продукта \"Сигареты\", страница 1', '1', '3'); INSERT INTO `pages` (`id`, `text`, `number`, `product_id`) VALUES ('6', 'Описание продукта \"Сигареты\", страница 2', '2', '3'); INSERT INTO `pages` (`id`, `text`, `number`, `product_id`) VALUES ('7', 'Описание продукта \"Хлеб\", страница 1', '1', '4'); INSERT INTO `pages` (`id`, `text`, `number`, `product_id`) VALUES ('8', 'Описание продукта \"Хлеб\", страница 2', '2', '4');[/sql] Вот что мы получили Код (Text): mysql> select * from products; +----+------------------+ | id | name | +----+------------------+ | 1 | Водка | | 2 | Пиво | | 3 | Сигареты | | 4 | Хлеб | +----+------------------+ Код (Text): mysql> select * from pages; +----+--------------------------------------------------------------------------+--------+------------+ | id | text | number | product_id | +----+--------------------------------------------------------------------------+--------+------------+ | 1 | Описание продукта "Водка", страница 1 | 1 | 1 | | 2 | Описание продукта "Водка", страница 2 | 2 | 1 | | 3 | Описание продукта "Пиво", страница 1 | 1 | 2 | | 4 | Описание продукта "Пиво", страница 2 | 2 | 2 | | 5 | Описание продукта "Сигареты", страница 1 | 1 | 3 | | 6 | Описание продукта "Сигареты", страница 2 | 2 | 3 | | 7 | Описание продукта "Хлеб", страница 1 | 1 | 4 | | 8 | Описание продукта "Хлеб", страница 2 | 2 | 4 | +----+--------------------------------------------------------------------------+--------+------------+ Все страницы по id продукта, id=1 - Описание продукта "Водка", страница 1 и Описание продукта "Водка", страница 2 [sql]SELECT `name`, `text` FROM `products` INNER JOIN `pages` ON `product_id` = `products`.`id` WHERE `product_id` = '1'[/sql] Код (Text): +------------+---------------------------------------------------------------------------+ | name | text | +------------+---------------------------------------------------------------------------+ | Водка | Описание продукта "Водка", страница 1 | | Водка | Описание продукта "Водка", страница 2 | +------------+---------------------------------------------------------------------------+ Страница по её id, id=4 - Описание продукта "Пиво", страница 2 [sql]SELECT `name`, `text` FROM `products` INNER JOIN `pages` ON `product_id` = `products`.`id` WHERE `pages`.`id` = '4'[/sql] Код (Text): +----------+------------------------------------------------------------------+ | name | text | +----------+------------------------------------------------------------------+ | Пиво | Описание продукта "Пиво", страница 2 | +----------+------------------------------------------------------------------+ Страница по id продукта и номеру страницы 3-2 - Описание продукта "Сигареты", страница 2 [sql]SELECT `name`, `text` FROM `products` INNER JOIN `pages` ON `product_id` = `products`.`id` WHERE `product_id` = '3' AND `number` = '2'[/sql] Код (Text): +------------------+--------------------------------------------------------------------------+ | name | text | +------------------+--------------------------------------------------------------------------+ | Сигареты | Описание продукта "Сигареты", страница 2 | +------------------+--------------------------------------------------------------------------+
Devzirom громадное громадное спасибо буду юзать наверно твой вариант. очень все подробно написано и понятно.)) сорвал спину и пишу эти строки почти сквозь слезы..не уседеть на стуле..)) пару дней и я сюда вернусь снова. надеюсь.. а пока меня хавтает только на спасибо и снова в кровать..
Вот я и ожил. ))) Начал делать рыбу по принципу, который предложил Devzirom Осталось несколько вопросов. Значит мой index приблизительной такой. PHP: <?php ini_set('display_errors',1); error_reporting(E_ALL); include('yzel.php'); $sql = "SELECT `name`, `text` FROM `products` INNER JOIN `pages` ON `product_id` = `products`.`id` WHERE `pages`.`number` = '1'"; $data = mysql_query($sql); echo "<table border=3>"; echo "<tr> <th>name</th> <th>about</th></tr>"; while($row=mysql_fetch_assoc($data)) { echo "<tr>"; echo '<td>'; echo $row['name']; echo '</td>'; echo '<td>'; echo "<a href='about.php?name=$row[name]'> about $row[name]</a>"; echo '</td>'; echo "</tr>"; } echo "</table>"; ?> вот файл about.php PHP: <?php ini_set('display_errors',1); error_reporting(E_ALL); include('yzel.php'); $name=$_GET['name']; $sql = "SELECT `text` FROM `products` INNER JOIN `pages` ON `product_id` = `products`.`id` WHERE `name`='$name' AND `pages`.`number` = '1'"; $data = mysql_query($sql); $row = mysql_fetch_assoc($data); echo $row['text']; // здесь бы надо сделать ссылку на страницу два или три в случае если они присутствуют. // что надо сделать снова запрос и проверку на empty ?? ?> Короче не понимаю как организовать навигацию на страницу 2 и 3 если они присутствуют. empty, count .. от чего отталкиваться можно решение или направьте ??))
header.php PHP: <?php header('Content-Type: text/html; charset=utf-8'); ini_set('display_errors', 1); error_reporting(E_ALL); define('PRODUCTS_ON_PAGE', 10); // Количество выводимых продуктов на странице $link = mysql_connect('localhost:3306', 'my', '_'); mysql_set_charset('utf8', $link); mysql_select_db('db2', $link); function not_found() { header("{$_SERVER['SERVER_PROTOCOL']} 404 Not Found"); die("404 Not Found"); } ?> index.php PHP: <?php // используйте require, если инклуд-файл критичен // используйте _once, чтобы присоединить инклуд только единожды require_once('header.php'); $part = isset($_GET['p']) ? (int) $_GET['p'] : 1; // Получить количество записей в таблице лучше всего так: $result = mysql_query("SELECT COUNT(*) FROM `products`"); $products_count = mysql_result($result, 0); mysql_free_result($result); // Желательно очищать результат $partsNum = ($products_count) ? ceil($products_count/PRODUCTS_ON_PAGE) : 1; // Самое время проверить, переданный в GET, параметр if($part < 1 || $part > $partsNum) return not_found(); // не объявляйте переменные, которые используете только один раз, // избегайте слишком длинных строк, // если не используете данные поля `text`, зачем его тащить? // следите за тем, что и зачем тащите из БД. $result = mysql_query(" SELECT `pages`.`id`, `name` FROM `products` INNER JOIN `pages` ON `product_id` = `products`.`id` WHERE `number` = '1' LIMIT ".($part-1)*PRODUCTS_ON_PAGE.", ".PRODUCTS_ON_PAGE); for($i=1; $i<$partsNum+1; $i++) { echo( ($i == $part) ? "\n<strong>{$i}</strong>" : "\n<a href=\"?p={$i}\">{$i}</a>"); } // Большое количество операторов echo, негативно сказывается на работе скрипта // Объём разметки в большинстве случаев превышает объемы php ?> <table border="3"> <tr><th>name</th><th>about</th></tr> <?php while($row = mysql_fetch_assoc($result)) { ?> <tr> <td><?php echo $row['name']; ?></td> <td><a href="about.php?id=<?php echo $row['id'] ?>">about <?php echo $row['name']; ?></a></td> </tr> <?php } mysql_free_result($result); ?> </table> about.php PHP: <?php require_once('header.php'); if(!isset($_GET['id'])) return not_found(); $id = (int) $_GET['id']; $result = mysql_query(" SELECT `pages`.`id`, `name`, `text`, (SELECT GROUP_CONCAT(`pages`.`id`) FROM `pages` WHERE `product_id` = `products`.`id` ORDER BY `number` ASC) AS `parts` FROM `pages` INNER JOIN `products` ON `product_id` = `products`.`id` WHERE `pages`.`id` = '{$id}'") or die(mysql_error()); $row = mysql_fetch_assoc($result); mysql_free_result($result); if(empty($row)) return not_found(); $parts = explode(',', $row['parts']); for($i=0; $i<count($parts); $i++) { echo( ($parts[$i] == $row['id']) ? "\n<strong>".($i+1)."</strong>" : "\n<a href=\"about.php?id={$parts[$i]}\">".($i+1)."</a>"); } echo "<div>{$row['text']}</div>"; ?>
Devzirom Да....на разбор твоего кода уйдут лучшие годы моей жизни..)) Я сделал пока так--- достаточно колхозно и чопорно но учитывая что контент разивается маскимум на 2-4 страницы я думаю пока сойдет файл about.php PHP: <?php ini_set('display_errors',1); error_reporting(E_ALL); include('yzel.php'); $name=$_GET['name']; if(!isset($_GET['n'])) { $sql = "SELECT `text` FROM `products` INNER JOIN `pages` ON `product_id` = `products`.`id` WHERE `name`='$name' LIMIT 0, 1"; $data = mysql_query($sql); while($row=mysql_fetch_assoc($data)) { echo $row['text']; echo '<br>'; } } else { $n=$_GET['n']; $n=($n-1); $sql = "SELECT `text` FROM `products` INNER JOIN `pages` ON `product_id` = `products`.`id` WHERE `name`='$name' LIMIT $n, 1"; $data = mysql_query($sql); while($m=mysql_fetch_assoc($data)) { echo $m['text']; echo '<br>'; } } $q="SELECT count(*) FROM `products` INNER JOIN `pages` ON `product_id` = `products`.`id` WHERE `name`='$name' "; $res=mysql_query($q); $row=mysql_fetch_row($res); $total_rows=$row[0]; $per_page=1; $num_pages=$total_rows/$per_page; $i=1; while($i<=$num_pages) { echo "<a href='about.php?name=$name&n=$i'>page $i</a>"; echo '<br>'; $i++; } ?>
Кстати хотел уточнить. Я же все делаю применительно к музыке. Поэтому ситуация такова: Что у меня по мимо описания истории создания группы, которая будет разбиваться на несколько страниц, также и треклист где альбомов 20-30 то же будет разбиваться на 2-3 страницы. Я правильно понимаю, что тогда мне имеет смысл делать третью таблицу с такой же связкой типа `id в основной таблице будет равен product_id в третьей. т.е. 1 таблица id и имя. 2 таблица-- описание истории создания 3 таблица -- треклист.
а разве mysql varchar не имеет ограничений по размеру? т.е. как он будет туда 20 стр. запихивать? не лучше в бд хранить ссылку на файл с описанием? , да и хостеры, обычнопод, бд выделяют не очень много места.
255 БАЙТ - варчар, в утф это даже не 255 букв... в тексте надо хранить текст =) А почему разговор зашел о варчарах? =)
забыл пароль от гугла? о фак щитовый! я забанен на гугле, мама! http://www.mysql.ru/docs/man/Storage_requirements.html
с меня пиво. дайте пепел, я посыплю себе свои седые мудя (фото, читать далее) и пойду менять всю архитектуру моих поделок *уходит в рыданиях* ЗЫ: блин, прикольно, чо. Буду знать.
[sql]CREATE TABLE `text` ( `foo` varchar(10) not null, UNIQUE KEY (`foo`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO `text` (`foo`) VALUES ('абвгдеёзжи');[/sql] Каждый символ весит 2 байта 10 * 2 = 20 байт
Dima4321 если всего 2-3 страницы, то заводить отдельные таблицы не обязательно. хотя если групп планируется много, то отдельные таблицы есть гут, только не две отдельные, а одна и для истории, и для треклиста. хотя всё зависит от твоей архитектуры. как придумаешь - так и будет
Gromo Групп будет очень много , несколько тысяч . Вопросы задаю с точки зрения оптимизации. Хочу,тобы мускул быстро бегал по таблицам. Т.е. найти оптимальное соотношение архитектруы и быстродействия с возможностью на будущее подмандить код в случае добавления новых премудростей или расщирения архитектуры. Т.е. по факту например 3000 групп и соотвоо id Из них выйдет 4000-5000 страниц истории И 4000-6000 страниц треклистов. Поэтому пока и склоняюсь к 3 таблицам.
отличное решение. только не храни текст истории, разбитый по страницам - храни текст в одном поле. удобнее редактировать, а на страницы можно и внутри пхп разбивать. насчёт треклистов нужно подумать - хранить их в виде хтмл можно только в случае, если не планируется использовать их как где-нибудь в другом виде.
Я уже замучался. Один говорит одно другой другое. ))) Базу же не рекомендуется парсить ??. Я хочу снизить нагрузку на выборку к минимуму. Т.е. никаких меток и прочих сложных алгоритмов извлечения. Текст будет попадать в базу уже с html тегами. Редактировать в будущем ничего практически не планируется. За исключением заголовков и подобной лабуды.
VARCHAR давно длиной 65536 байт, при чем места для поля выделяется ровно столько, сколько нужно, а не сколько задано в таблице. Но не больше заданного в таблице.
Dima4321 давай заново переформулируй уже на новом уровне понимания процессов. и не одной кучей текста, которую ты наложил там наверху, а по пунктам. =) Вобще проектирование базы надо начинать с описания "сущностей". А кстати все страницы первые вторые третьи десятые можно хранить в одной базе, просто поле присобачь "номер страницы"