Какие виды ключей в базе данных ты знаешь?

Ответ

При работе с базами данных в Flutter-приложениях (обычно через пакеты вроде sqflite или moor) я сталкиваюсь со следующими видами ключей:

  1. Первичный ключ (Primary Key, PK) — уникально идентифицирует каждую запись в таблице. Не может быть NULL. В sqflite часто реализуется как автоинкрементное поле id.

    // Пример создания таблицы с первичным ключом в sqflite
    await db.execute('''
      CREATE TABLE Users (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL
      )
    ''');
  2. Внешний ключ (Foreign Key, FK) — создает связь между таблицами, ссылаясь на первичный ключ другой таблицы. Обеспечивает ссылочную целостность.

    await db.execute('''
      CREATE TABLE Orders (
        id INTEGER PRIMARY KEY,
        user_id INTEGER,
        FOREIGN KEY (user_id) REFERENCES Users(id)
      )
    ''');
  3. Уникальный ключ (Unique Key) — гарантирует, что все значения в столбце (или комбинации столбцов) уникальны. В отличие от PK, допускает одно значение NULL.

    await db.execute('''
      CREATE TABLE Products (
        id INTEGER PRIMARY KEY,
        sku TEXT UNIQUE
      )
    ''');
  4. Составной ключ (Composite Key) — первичный ключ, состоящий из двух или более столбцов. Используется, когда уникальность определяется их комбинацией.

    await db.execute('''
      CREATE TABLE OrderItems (
        order_id INTEGER,
        product_id INTEGER,
        quantity INTEGER,
        PRIMARY KEY (order_id, product_id)
      )
    ''');
  5. Суррогатный ключ — искусственный, не несущий бизнес-смысла ключ (например, автоинкрементный id). Чаще всего используется в Flutter-приложениях.

  6. Естественный ключ — первичный ключ на основе реальных бизнес-данных (например, email или номер паспорта). На практике в мобильных приложениях используется реже из-за возможных изменений этих данных.

Ключи критически важны для построения связей между данными, обеспечения целостности и оптимизации запросов через индексы.

Ответ 18+ 🔞

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

Представь себе, что твоя база данных — это такой огромный склад, где всё валяется в одной куче. Без ключей это будет пиздопроебибна, найти что-то — хуй с горы. Вот чтобы не было такого пиздеца, и придумали систему.

1. Первичный ключ (Primary Key, PK) Это, ёпта, главный паспорт каждой записи. Как отпечатки пальцев у человека — уникальные и нихуя не повторяются. В sqflite его обычно делают из поля id, которое само растёт, как на дрожжах. Без него — нихуя не работает, он не может быть пустым, это святое.

// Создаём таблицу пользователей. Видишь этот id? Это он, красавец.
await db.execute('''
  CREATE TABLE Users (
    id INTEGER PRIMARY KEY AUTOINCREMENT, // Вот он, сука, главный!
    name TEXT NOT NULL
  )
''');

Без этого PRIMARY KEY твоя таблица — просто манда с ушами, бесполезная куча данных.

2. Внешний ключ (Foreign Key, FK) А вот это уже интереснее. Это как ниточка, которая связывает две таблицы. Допустим, у тебя есть пользователь и его заказы. Чтобы не писать имя пользователя в каждый заказ (а оно может поменяться, и тогда пиздец), ты просто пишешь user_id — ссылку на запись в таблице Users. Умно, да? Целостность данных на уровне, доверия ебать ноль, потому что база сама следит, чтобы ты не привязал заказ к несуществующему юзеру.

await db.execute('''
  CREATE TABLE Orders (
    id INTEGER PRIMARY KEY,
    user_id INTEGER, // Смотри-ка, а это чё?
    FOREIGN KEY (user_id) REFERENCES Users(id) // Ага, вот и привязка! Чистая магия.
  )
''');

3. Уникальный ключ (Unique Key) Ну, тут название говорит само за себя. Он не главный, но тоже требует, чтобы значения в столбце не повторялись. Например, артикул товара (sku). Два одинаковых артикула — волнение ебать, где логика? Хотя NULL он, в отличие от первичного ключа, стерпит.

await db.execute('''
  CREATE TABLE Products (
    id INTEGER PRIMARY KEY,
    sku TEXT UNIQUE // Попробуй вставить два одинаковых — получишь в рот меня чих-пых, то есть ошибку.
  )
''');

4. Составной ключ (Composite Key) Бывает, что одной колонки для уникальности мало. Например, позиция в заказе: order_id и product_id. По отдельности они повторяются овердохуища раз, а вот их комбинация — уже уникальна. Вот для этого и склеивают их в один составной первичный ключ. Хитрая жопа, но работает.

await db.execute('''
  CREATE TABLE OrderItems (
    order_id INTEGER,
    product_id INTEGER,
    quantity INTEGER,
    PRIMARY KEY (order_id, product_id) // Уникальность — в паре! Как Бонни и Клайд.
  )
''');

5. Суррогатный vs Естественный ключ Тут философия, ёпта.

  • Суррогатный — это наш старый добрый автоинкрементный id. Он не несёт никакого смысла, просто номер в очереди. Зато стабильный, простой и всем нравится. В 99% случаев в мобилках юзают именно его.
  • Естественный — это когда в роли ключа выступают реальные данные: email, номер телефона, ИНН. В теории красиво, на практике — пиздец. Потому что email может поменяться, номер телефона — тоже, а первичный ключ менять — это ж надо всю базу перетряхивать. Представь, что у всех твоих записей поменялся паспорт. Удивление пиздец. Поэтому на него обычно забивают хуй.

Короче, вся эта система ключей — она не просто так. Это чтобы твои данные не превратились в кашу, связи работали чётко, а поиск был быстрым. Без них твой код накроется медным тазом при первой же попытке что-то сложнее "Hello, World!" сделать.