Задать вопрос
Ответы пользователя по тегу MySQL
  • Как лучше организовать хранение множественных текстовых данных?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Ну, по сути это метаданные для модели филиал. Имхо тут 3 варианта:

    – хранить все эти метаданные в одном поле в таблице филиала, в виде JSON
    – хранить данные в отдельной таблице, структурировано – с колонками под все эти метаданные
    – хранить данные в отдельной таблице long and skinny – в виде id | branch_id | key | value

    Как по мне, то структурированная таблица здесь – перебор. Таблица для метаданных – субъективная штука. Кому-то нравится, кому-то нет. JSON – современно, модно, молодежно. В PostgreSQL нативно и быстро, в MariaDB почти нативно и почти так же быстро, в MySQL хз, давно не заглядывал. Думаю уже должны были решить.
    Ответ написан
    Комментировать
  • Как проверить имеющуюся идентичную строку перед вставкой новой?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    INSERT INTO my_table (login, host, event_id) 
    SELECT 'strelkov.av', 'home_pc', 1
    FROM my_table
    WHERE login='strelkov.av' 
    AND host='home_pc'
    AND event_id=1
    HAVING COUNT(*)=0;

    Обратите внимание, что значения login, host и event_id вам в 2х местах надо указывать. Работает это дело так - если конструкция SELECT ... HAVING COUNT(*)=0 вернет true (то есть SELECT не нашел записи с таким логином, хостом и ID ивента), то будет выполнен INSERT. Если же SELECT вернет false (COUNT не равен 0, значит такая строка уже существует), то INSERT будет проигнорирован целиком. Понимаю, что это не сразу вкуривается, но SQL штука интересная :)

    PS: Подразумевается, что id у вас AUTO_INCREMENT, а у date DEFAULT NOW() и их передавать вообще не надо.
    Ответ написан
  • Обязательно ли записи продуктов должны хранится в одной таблице бд?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Количество продуктов от 100 000 до 500 000

    Не хочу сильно нагружать бд


    500к записей для MySQL это не нагрузка. Адекватные индексы и не нужно заниматься преждевременной оптимизацией там, где она вообще лишняя.
    Ответ написан
    Комментировать
  • Как совместить выборку значений и Count()?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    SELECT SQL_CALC_FOUND_ROWS p.product_id
    FROM product_to_category p2c 
    LEFT JOIN product p ON (p2c.product_id = p.product_id)  
    WHERE p2c.category_id = '66'

    Вернет product_ids.
    Дополнительным запросом
    SELECT FOUND_ROWS()
    Можно получить количество строк. Запрос будет быстрым, так что таких 2 запроса это не то же самое, что 2 запроса с джоинами. Впрочем, первый запрос с SQL_CALC_FOUND_ROWS может быть медленнее чем 2 запроса - все зависит от конкретной структуры данных, индексов.

    ЗЫ: Запрос по памяти писал, подходящих данных для тестирования нет, поэтому может придется покрутить.
    ЗЗЫ: А вообще на тему SQL_CALC_FOUND_ROWS холивары годами идут. По производительности есть вопросы и много "если". Да и MySQL вроде как его потихоньку депрекейтит. Впрочем, так или иначе - это инструмент. Сами решайте, имеет ли смысл использовать его в вашем конкретном случае.
    Ответ написан
    Комментировать
  • Должна ли быть колонка в таблице, если она будет не заполнена у некоторых пользователей?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    она может быть не заполнена (null).

    Она заполнена. NULL это валидное значение, такое же как и любое другое.

    или сделать отдельную таблицу с этой колонкой

    Лишнее. Это дополнительный запрос или JOIN. Выигрыша ноль.

    Почитайте про кардинальность. Нету ничего плохого в том, чтобы часть записей имело NULL в колонке, которая не является обязательной. Вот если таких колонок становится много и их все условно можно отнести в категорию secondary/metadata - например, они не используются на выводе "все пользователи" (индекс), а нужны только при просмотре одного конкретного пользователя - вот тогда можно думать о том, чтобы выносить эти данные в отдельную таблицу. Например, будет users и user_data, в которой и будут эти колонки. На индексе вы будете запрашивать только users, на одном пользователе - обе таблицы.
    Ответ написан
    Комментировать
  • Как изменить счетчик автоматического увеличения в MySQL на php?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Как изменить счетчик автоматического увеличения в MySQL

    ALTER TABLE table_name AUTO_INCREMENT = value;

    на php?

    Выполнить этот запрос из PHP.
    Ответ написан
  • Какой из способов организации хранения адресов и данных паспорта выбрать?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Павел Чесноков дело говорит, а по сути:
    - User hasOne Passport / Passport belongsTo User (связь OneToOne)
    С адресами чуток сложнее, тут я бы сами адреса хранил отдельно через связь OneToMany, с дополнительным свойством type. А вот isAddressSimilar и isAddressPlaceOfStay - либо флагами в User, либо вообще динамическим свойством - например если записи адреса с типом place_of_stay не существует, то юзаем дефолтный (registration) или просто возвращаем false. Ибо хранить записи где все колонки кроме PK null это не ок.
    Ответ написан
    4 комментария
  • В Laravel все в БД должно быть сущностями?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Enum'ы не очень ок, не используйте их. Потом рефакторить больше гемора чем удобства / пользы от них.
    2. Не все обязательно должно быть сущностями, но в основном да - так удобнее.
    3. В вашем случае в самой простой реализации это связь oneToMany - User hasMany Socials / Social belongsTo User (дополнительные данные хранятся в таблице socials):

    Таблица users: id | email | ...
    Таблица socials:
    id | user_id (foreign key) | external_social_id | title | ...


    Но здесь у вас будет дублирование всех данных по каждой соцсети - начиная от поля title и далее (а что там - зависит от проекта. Вполне возможно там еще API key может быть, иконку привязать, урл и тд). Поэтому такая БД не будет адекватно нормализована. Если по соцсети у вас будет более 1 поля name/title, то разумнее делать связь manyToMany с использованием pivot.

    Связь manyToMany - User belongsToMany Socials / Social belongsToMany Users (дополнительные данные расходятся по таблицам - все что уникально для Social в socials, все что касается связи - в pivot):

    Таблица users: id | email | ...
    Таблица socials: id | title | icon_path | ...
    Таблица social_user:
    social_id (foreign key) | user_id (foreign key) | external_social_id | ...


    В моделях:
    // User
    public function social()
    {
        return $this->belongsToMany(Social::class)->withPivot(['external_social_id']);
    }
        
    // Social
    public function user()
    {
        return $this->belongsToMany(User::class)->withPivot(['external_social_id']);
    }


    Если такая динамичная сущность связи со временем растет и усложняется, делаем из нее полноценную сущность, создавая свою модель (class SocialUser extends Pivot).
    Ответ написан
    Комментировать
  • Что такое Cardinality и зачем оно нужно?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Cardinality характеризует уникальность данных. Высокая кардинальность - уникальные данные, низкая кардинальность - повторяющиеся данные. Например, в таблице customers имеем колонки:
    • gender - высокоповторяющиеся данные, низкая кардинальность
    • city - данные повторяются, но уже не так часто - нормальная кардинальность
    • phone - данные уникальны, высокая кардинальность


    Как кардинальность может слететь - впервые слышу. Это характеристика данных по их уникальности, а не индекс какой-нибудь. Она не слетает.

    Впрочем, иногда под кардинальностью (скорее ошибочно) подразумевают кардинальные отношения между таблицами (1:1, 1:n, n:n). В данном случае тогда речь может идти о слетевших связях (foreign keys слетевшие в результате некорректного импорта с переопределением autoincrements).
    Ответ написан
    2 комментария
  • Как вывести список всех таблиц MySQL и количество строк в каждой из них впри помощи PHP?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    SHOW TABLES FROM database_name прекрасно работает когда база не выбрана. Здесь мы показываем таблицы в базе, а не в $db_table. Исходя из вашего нейминга, вы просите таблицу показать ее таблицы, что абсурдно само по себе. Обращайтесь к базе. Или, если вы базу предварительно уже выбрали, то достаточно SHOW TABLES.

    Далее, для SELECT * FROM table_name уже сначала нужно выбрать базу данных (которую вы опрашивали на предмет таблиц в первом запросе), или же обращаться к таблице в формате database_name.table_name.

    Ну и, вместо того чтобы делать выборку всех строк со всеми колонками, спросите сразу SELECT COUNT(*) FROM database_name.table_name.

    Еще проще и быстрее это сделать с помощью такого запроса:

    SELECT table_name, table_rows
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_SCHEMA = 'your_database_name';


    Результат этого запроса:

    +-----------------------+------------+
    | table_name            | table_rows |
    +-----------------------+------------+
    | wp_terms              |         10 |
    | wp_yoast_seo_meta     |         61 |
    | wp_yoast_seo_links    |         33 |
    | wp_commentmeta        |          0 |
    | wp_term_taxonomy      |         10 |
    | wp_ewwwio_queue       |        352 |
    | wp_usermeta           |        114 |
    | wp_options            |        281 |
    | wp_users              |          5 |
    | wp_term_relationships |         49 |
    | wp_ewwwio_images      |       1048 |
    | wp_links              |          0 |
    | wp_postmeta           |      21408 |
    | wp_termmeta           |          0 |
    | wp_comments           |          0 |
    | wp_posts              |        738 |
    +-----------------------+------------+


    Единственное, что нужно учесть - если таблицы у вас InnoDB, то данные цифры будут более-менее точными, но не совсем. В силу механизмов оптимизации. Так что если нужно "приблизительно" понимать - используйте данный метод. Если нужно с точностью до одной строки - тогда COUNT.

    Ну и еще можно сделать SHOW TABLE STATUS, находять в выбранной базе данных. Точность подсчета количества строк на InnoDB такая же, как и предыдущем методе, но зато здесь будет еще много полезной информации. Например - avg_row_length, data_length, index_length и другое.
    Ответ написан
    4 комментария
  • Редактирование таблиц БД из админки WordPress. Какой подход?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Класс wpdb.
    Ответ написан
    Комментировать
  • Как правильно составить запрос в БД Woocommrce?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    1. Поле _price находится в wp_postmeta, а не wp_posts
    2. Поле kyrs (кстати, такая транслитерация слова "курс" является примером говнокода) тоже скорее всего в wp_postmeta
    3. Вам всем товарам с полем kyrs одинаковую цену выставить надо?
    4. В один запрос это формировать не факт что разумно. Сначала получите ID записей, которые post_type=product + post_status=publish + имеют meta_key 'kyrs'. А потом уже с этим массивом ID работайте, устанавливая нужные цены в таблицу wp_postmeta.
    Ответ написан
  • Переливание пользователей в МЛМ матричной системе?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Посмотрите в сторону процессинга на PHP с помощью рекурсии. Для МЛМ-матриц рекурсии – самое оно. Глядишь, и код перестанет так сильно пахнуть.
    Ответ написан
    1 комментарий
  • Как лучше парсить из файла в базу wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Для больших объемов, когда грозят таймауты, используйте WP-CLI
    Ответ написан
    3 комментария
  • Как использовать одну базу пользователей на 2х сайтах wordpress?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    С помощью констант в wp-config.php можно указать кастомные таблицы wp_user / wp_usermeta. Укажите одни и те же для обеих сайтов в их конфигах:

    define( 'CUSTOM_USER_TABLE', $shared_table_prefix . 'my_users' );
    define( 'CUSTOM_USER_META_TABLE', $shared_table_prefix . 'my_usermeta' );
    Ответ написан
    4 комментария
  • Сильно ли сократится нагрузка/ответ от сервера при таком раскладе?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вариант 1: Вместо MySQL используйте Redis.
    Вариант 2: Продолжайте использовать MySQL, но добавьте кеш в Memcached / Redis.
    Ответ написан
    5 комментариев
  • Оптимальная конфигурация для сервера?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Если вопрос поставлен таким образом - то current stable, то есть PHP 7.2 и MariaDB 10.2.
    Главное - убедиться, что ваш код работает с ними как положено.
    Ответ написан
    Комментировать
  • Почему тормозит SELECT запрос (выполняется 0.5 сек)?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Вообще по поведению похоже на обычную работу кеша. Данные обновились, кеш инвалидируется и холодный запрос занимает 0,5с. После его выполнения результат кешируется, поэтому последующее выполнение запроса происходит "мгновенно". Грубо говоря, 0,5с - это и есть реальное время выполнения этого запроса. Вот только почему у вас нету такого с wp_postmeta - вот это уже интересно.
    Ответ написан
    3 комментария
  • Можно ли это все связать в одном запросе?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    JOIN в MySQL является синонимом INNER JOIN. А в вашем случае, если я правильно понял ваше сумбурное описание, нужен LEFT JOIN.

    Впрочем, описание у вас весьма сложное для понимания, и без schema и примерных данных сложно понять все целиком.
    Ответ написан
  • Как сделать два столбца уникальными?

    HeadOnFire
    @HeadOnFire
    PHP, Laravel & WordPress Evangelist
    Ответ написан
    Комментировать