За последние 24 часа нас посетили 17923 программиста и 1716 роботов. Сейчас ищут 2198 программистов ...

Правильна ли логика построения БД и вывода в PHP

Тема в разделе "PHP и базы данных", создана пользователем lemonl, 22 ноя 2021.

  1. lemonl

    lemonl Активный пользователь

    С нами с:
    10 июн 2009
    Сообщения:
    164
    Симпатии:
    0
    Здравствуйте,

    Подскажите правильная ли логика построения БД такой структуры.

    [​IMG]



    CREATE TABLE IF NOT EXISTS `golog` (
    `date` TIMESTAMP NULL DEFAULT NULL,
    `meta_key` varchar(100) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
    `meta_value` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0'
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;



    INSERT INTO `golog` (`date`, `meta_key`, `meta_value`) VALUES
    ('2021-11-21 14:56:03', 'all_sum', '125'),
    ('2021-11-21 14:56:03', 'type', 'C1'),
    ('2021-11-21 14:56:03', 'max_type_c1', '122'),
    ('2021-11-21 14:56:03', 'rez_type_h1', '100'); // Если больше 100 квадратик зеленый, меньше 0 красный
    COMMIT;

    В верхних и нижних блоках есть иерархия Z.. и О.. всегда в последовательном ранге ближе к центру разделения, а далее в последовательном ранге идут J.. и C..


    Блоки строятся так:
    Код (Text):
    1.   <style>
    2. .bl {
    3.   width:1.72rem;
    4.   height:.9rem;
    5.   border:1px solid #ececec;
    6.   display: inline-flex;
    7.   justify-content: center;
    8.   align-items: center;
    9.   vertical-align: middle;
    10.   user-select: none;
    11.   position: relative;
    12.   font-size:.7rem;
    13.   margin:1px;
    14. }
    15. </style>
    16.  
    17. <div class="block" style="width:30px;display:inline-flex;">
    18.     <div class="block" style="width:30px;display: inline-flex;margin:0px;">
    19.       <div class="bl" style="font-size:.6rem;background:#fdf8d0;">25.08</div>
    20.       <div class="bl" style="font-size:.6rem;background:#eaf2f2;">125</div>
    21.     </div>
    22.     <div class="block" style="width:30px;display:inline-flex;margin:0px;background:#ff6a6a;">
    23.       <div class="bl" style="margin-bottom:0;font-size:.7rem;border-bottom:0;">J5</div>
    24.       <div class="bl" style="margin-top:0;font-size:.6rem;background:#f7f7e2;border-top:0;">98</div>
    25.     </div>
    26.     <div class="block" style="width:30px;display:inline-flex;margin:0px;background:#ff6a6a;">
    27.       <div class="bl" style="margin-bottom:0;font-size:.7rem;border-bottom:0;">J1</div>
    28.       <div class="bl" style="margin-top:0;font-size:.7rem;background:#f7f7e2;border-top:0;">10</div>
    29.     </div>
    30.     <div class="block" style="width:30px;display:inline-flex;margin:0px;background:#ff6a6a;">
    31.       <div class="bl" style="margin-bottom:0;font-size:.7rem;border-bottom:0;">O5</div>
    32.       <div class="bl" style="margin-top:0;font-size:.6rem;background:#f7f7e2;border-top:0;">98</div>
    33.     </div>
    34.     <div class="block" style="width:30px;display:inline-flex;margin:0px;background:#06b500;">
    35.       <div class="bl" style="margin-bottom:0;font-size:.7rem;border-bottom:0;">O4</div>
    36.       <div class="bl" style="margin-top:0;font-size:.6rem;background:#f7f7e2;border-top:0;">19</div>
    37.     </div>
    38.     <div class="block" style="width:30px;display:inline-flex;margin:0px;background:#06b500;">
    39.       <div class="bl" style="margin-bottom:0;font-size:.7rem;border-bottom:0;">O2</div>
    40.       <div class="bl" style="margin-top:0;font-size:.6rem;background:#f7f7e2;border-top:0;">19</div>
    41.     </div>
    42.     <div class="bl" style="height:2px;background:#222;"></div>
    43.     <div class="block" style="width:30px;display: inline-flex;margin:0px;background:#ff6a6a;">
    44.       <div class="bl" style="margin-bottom:0;font-size:.7rem;border-bottom:0;">Z5</div>
    45.       <div class="bl" style="margin-top:0;font-size:.6rem;background:#f7f7e2;border-top:0;">9</div>
    46.     </div>
    47.     <div class="block" style="width:30px;display: inline-flex;margin:0px;background:#ff6a6a;">
    48.       <div class="bl" style="margin-bottom:0;font-size:.7rem;border-bottom:0;">C1</div>
    49.       <div class="bl" style="margin-top:0;font-size:.6rem;background:#f7f7e2;border-top:0;">9</div>
    50.     </div>
    51.     <div class="block" style="width:30px;display: inline-flex;margin:0px;background:#ff6a6a;">
    52.       <div class="bl" style="margin-bottom:0;font-size:.7rem;border-bottom:0;">C2</div>
    53.       <div class="bl" style="margin-top:0;font-size:.6rem;background:#f7f7e2;border-top:0;">11</div>
    54.     </div>
    55.   </div>

    Подскажите как правильно вывести из БД в PHP такие данные. Таких блоков будет около 4000
     
  2. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.858
    Симпатии:
    748
    Адрес:
    Татарстан
    я тупой наверное но по картинкам ни структуры БД ни логики не вижу...

    может по человечески попытаетесь объяснить - что вы хотите хранить в БД, какие данные, как они связаны друг с другом и прочее?
     
  3. lemonl

    lemonl Активный пользователь

    С нами с:
    10 июн 2009
    Сообщения:
    164
    Симпатии:
    0
    Данные выводятся в такие блоки в зависимости от даты
    [​IMG]
    Пример данных из БД за 28,08

    INSERT INTO `golog` (`date`, `meta_key`, `meta_value`) VALUES
    ('2021-11-21 14:56:03', 'all_sum', '125'),
    /* FOR TOP DATA */
    ('2021-11-21 14:56:03', 'type', 'O2'),
    ('2021-11-21 14:56:03', 'max_type_o2', '19'),
    ('2021-11-21 14:56:03', 'rez_type_o2', '100'),

    ('2021-11-21 14:56:03', 'type', 'O4'),
    ('2021-11-21 14:56:03', 'max_type_o4', '19'),
    ('2021-11-21 14:56:03', 'rez_type_o4', '100')

    ('2021-11-21 14:56:03', 'type', 'O5'),
    ('2021-11-21 14:56:03', 'max_type_o5', '98'),
    ('2021-11-21 14:56:03', 'rez_type_o5', '-50'),

    ('2021-11-21 14:56:03', 'type', 'J1'),
    ('2021-11-21 14:56:03', 'max_type_j1', '10'),
    ('2021-11-21 14:56:03', 'rez_type_j1', '-12'),

    ('2021-11-21 14:56:03', 'type', 'J5'),
    ('2021-11-21 14:56:03', 'max_type_j5', '98'),
    ('2021-11-21 14:56:03', 'rez_type_j5', '-33'),

    /* FOR BOTTOM DATA */
    ('2021-11-21 14:56:03', 'type', 'Z5'),
    ('2021-11-21 14:56:03', 'max_type_z5', '19'),
    ('2021-11-21 14:56:03', 'rez_type_z5', '100'),

    ('2021-11-21 14:56:03', 'type', 'C1'),
    ('2021-11-21 14:56:03', 'max_type_c1', '9'),
    ('2021-11-21 14:56:03', 'rez_type_c1', '-11')

    ('2021-11-21 14:56:03', 'type', 'c2'),
    ('2021-11-21 14:56:03', 'max_type_c2', '11'),
    ('2021-11-21 14:56:03', 'rez_type_c2', '-50');
    COMMIT;
     
  4. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.858
    Симпатии:
    748
    Адрес:
    Татарстан
    допустим, хотя понятнее не стало...
    вы конкретно что хотите?
     
  5. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.487
    Симпатии:
    281
    Если вы, по каким-то причинам не можете изменить структуру этой таблицы, то для требуемой вам выборки придется пользоваться самообъединением таблицы.
    Если же структура не принципиальна, то вместо одной таблицы сделайте три. С общей колонкой, и объединяйте по ней.
    Потому, что самообъединение понадобится довольно хитрое - с извлечением подстрок.
     
  6. lemonl

    lemonl Активный пользователь

    С нами с:
    10 июн 2009
    Сообщения:
    164
    Симпатии:
    0
    Хочу выводить информацию из БД.
    Идет набор последовательных дней, в каждом из дней есть маркеры которые появляются.

    Есть два главных параметра:
    1. Дата (день)
    2. Вся сума дня

    В дне присутствуют маркеры и их значение (В верхних и нижних блоках есть иерархия Z.. и О.. всегда в последовательном ранге ближе к центру разделения, а далее в последовательном ранге идут J.. и C..)
    ('2021-11-21', 'type', 'J5'),
    ('2021-11-21', 'max_type_j5', '98'),


    А так ?)
     
  7. lemonl

    lemonl Активный пользователь

    С нами с:
    10 июн 2009
    Сообщения:
    164
    Симпатии:
    0
    Код (Text):
    1.  
    2. Таблица 2 Markers:
    3. -----------------
    4. Date         |Type   |MAX_Type  | REZ_type
    5. -----------------
    6. 2021-11-10   | C1    |  88      |    -22        
    7. 2021-11-10   | C2    |  22      |    44    
    8. 2021-11-11   | J1    |  19      |    -9  
    9.  
    10. Таблица 1 Period:
    11. -----------------
    12. Date         | all_sum
    13. ----------------
    14. 2021-11-10   | 200
    15. 2021-11-11   | 100
    16. 2021-11-12   | 300
    17.  
    18.  
    19. Ожидаемый результат:
    20. -------------------------
    21. 2021-11-10 |200| C1 88 -22, C2 22 44, .... , ....
    22. 2021-11-11 |100| J1 19 -9, .... , ....  
     
  8. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.858
    Симпатии:
    748
    Адрес:
    Татарстан
    очень неадекватная структура БД

    но если так хотите, то как-то так
    Код (Text):
    1. SELECT p.all_sum, GROUP_CONCAT(p.type) AS v1, GROUP_CONCAT(MAX_type) AS v2,
    2. GROUP_CONCAT(REZ_type) AS v3  FROM Period AS p
    3. LEFT JOIN Markers As m IN m.date = p.date
    4. GROUP BY p.date
    так же крайне неадекватно, + ограничение на длину результата GROUP_CONCAT в 1024 символа

    по хорошему - попытаться объяснить что эти поля значат зачем, каков реальный смысл данных, вам подскажут нормальную структуру БД для их хранения, и все запросы станут легче
     
  9. lemonl

    lemonl Активный пользователь

    С нами с:
    10 июн 2009
    Сообщения:
    164
    Симпатии:
    0
    Каждый будний (за исключением выходных) проводится анализ состояния сельхозземли. На основе полученных данных нужно построить диаграмму.

    Входящие данные за день:

    1. Дата
    2. Показатель влажности земли

    3. Маркеры для анализа состояния земли
    * Название маркера: Нижние блоки (Z2,Z3,Z4,Z5) (C1,C2,C3,C4,C5) и Верхние блоки (O2,O3,O4,O5) (J1,J2,J3,J4,J5)
    * Значение маркера
    * Критическое значение маркера // Если значение больше 100 квадратик зеленый, меньше 0 красный


    Для удобного отображения данных для человеческого глаза при выводе строятся по следующему типу.

    28.05 - ДАТА анализа 28 мая
    155 - Показатель влажности земли

    J5
    J4
    J3
    J2
    J1

    O5

    O4

    O3

    O2
    О&& - более важный поэтому они всегда идут ближе к разделителю, J&& - идут после
    ---- РАЗДЕЛИТЕЛЬ, между верхним и нижним блоком маркеров
    Z&& - более важный поэтому они всегда идут ближе к разделителю, С&& - идут после
    Z2
    Z3
    Z4
    Z5

    C1
    C2
    C3
    C4
    C5
     
  10. ADSoft

    ADSoft Старожил

    С нами с:
    12 мар 2007
    Сообщения:
    3.858
    Симпатии:
    748
    Адрес:
    Татарстан
    Ну я бы сделал че-нить типа такого

    Код (Text):
    1.  
    2. markers
    3. -----------------
    4. period_id      |Type   |MAX_Type  | REZ_type | sort
    5. -----------------
    6. 1   | C1    |  88      |    -22        | 1
    7. 1  | C2    |  22      |    44          |  2
    8. 2   | J1    |  19      |    -9   |  3
    period
    PHP:
    1. id | Date         | all_sum
    2. ----------------
    3. 1   | 2021-11-10   | 200
    4. 2   | 2021-11-11   | 100
    5. 3   | 2021-11-12   | 300
    --- Добавлено ---
    за большой период чтоб строить данные- можно выбрать за определенный промежуток все данные в массив,
    а уже на стороне php группировать массивы по периодам - и строить отображение периодов
    sort ввел, чтоб сортировку проще ыло нативную делать, чем голову ломать какой тип выше ниже
     
  11. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.487
    Симпатии:
    281
    Здесь, на мой взгляд, достаточно, просто объединить таблицы по дате, и отсортировать по двум колонкам - Date и Type
     
  12. lemonl

    lemonl Активный пользователь

    С нами с:
    10 июн 2009
    Сообщения:
    164
    Симпатии:
    0
    Я так и сделал...
    Код (Text):
    1.  
    2.   $sql = "SELECT M.rank, M.date, M.type_marker FROM markers M INNER JOIN period P ON M.date = P.date WHERE M.rank LIKE 'T%' ORDER BY M.date DESC, M.rank DESC";
    3.   $result = $conn->query($sql);
    4.   if ($result->num_rows > 0) {
    5.   while($top = $result->fetch_assoc()) {
    6.   echo "rank: " . $top["rank"]. " date: " . $top["date"]. " type: " . $top["type_marker"].  "<br>";
    7.   }
    8.   } else {
    9.   echo "0";
    10.   }
    вот что у меня получилось
    http://desaps.000webhostapp.com/z.php

    А как вывести эти данный поблочно по дате. Сейчас все идет одной строкой
     
    #12 lemonl, 18 дек 2021
    Последнее редактирование: 18 дек 2021
  13. lemonl

    lemonl Активный пользователь

    С нами с:
    10 июн 2009
    Сообщения:
    164
    Симпатии:
    0
  14. lemonl

    lemonl Активный пользователь

    С нами с:
    10 июн 2009
    Сообщения:
    164
    Симпатии:
    0
    Подскажите пожалуйста, а так правильно делать

    Код (Text):
    1. $sqlPeriod = "SELECT * FROM `period` ORDER BY `period`.`date` DESC";
    2. $result = $conn->query($sqlPeriod);
    3. if ($result->num_rows > 0) {
    4. while($period = $result->fetch_assoc()) {
    5.     echo "id: " . $period["id"]. " date: " . $period["date"]. " type: " . $period["vol"]."<br>";
    6.    
    7.     $sqlT = "SELECT M.rank, M.date, M.type_marker FROM markers M WHERE M.date='".$period["date"]."' AND M.rank LIKE 'T%' ORDER BY M.date DESC, M.rank DESC";
    8.     $resultT = $conn->query($sqlT);
    9.     if ($resultT->num_rows > 0) {
    10.       while($top = $resultT->fetch_assoc()) {
    11.         echo "rank: " . $top["rank"]. " date: " . $top["date"]. " type: " . $top["type_marker"]."<br>";
    12.       }
    13.     } else {
    14.       echo "0";
    15.     }
    16.     echo "---------------------------------------<br>";
    17.     $sqlB = "SELECT M.rank, M.date, M.type_marker FROM markers M WHERE M.date='".$period["date"]."' AND M.rank LIKE 'B%' ORDER BY M.date DESC, M.rank ASC";
    18.     $resultB = $conn->query($sqlB);
    19.     if ($resultB->num_rows > 0) {
    20.       while($bottom = $resultB->fetch_assoc()) {
    21.         echo "rank: " . $bottom["rank"]. " date: " . $bottom["date"]. " type: " . $bottom["type_marker"].  "<br>";
    22.       }
    23.     } else {
    24.       echo "0";
    25.     }
    26.  
    27.     echo "<br><br>";
    28. }
    29. } else {
    30.       echo "NO DATA";
    31. }
     
  15. Drunkenmunky

    Drunkenmunky Активный пользователь

    С нами с:
    12 авг 2020
    Сообщения:
    1.487
    Симпатии:
    281
    Если работает, то почему нет.