← Назад к вопросам

В чем разница между DDL и DML?

1.0 Junior🔥 181 комментариев
#Базы данных и SQL

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# DDL vs DML: Различия и применение

Определение

DDL (Data Definition Language) - язык определения данных. Используется для создания, изменения и удаления структуры базы данных.

DML (Data Manipulation Language) - язык манипулирования данными. Используется для работы с самими данными внутри существующей структуры.

Основные различия

DDL - Определение структуры

DDL операции изменяют саму схему базы данных:

-- CREATE - создание объектов
CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(100) UNIQUE
);

-- ALTER - изменение структуры
ALTER TABLE users 
ADD COLUMN age INT DEFAULT 0;

ALTER TABLE users 
DROP COLUMN age;

ALTER TABLE users 
MODIFY COLUMN email VARCHAR(150);

-- DROP - удаление объектов
DROP TABLE users;

-- TRUNCATE - удаление всех строк (но сохраняет структуру)
TRUNCATE TABLE users;

-- RENAME - переименование
RENAME TABLE users TO app_users;

-- CREATE INDEX - создание индекса
CREATE INDEX idx_email ON users(email);

DML - Работа с данными

DML операции работают с самими данными:

-- SELECT - выборка данных
SELECT * FROM users WHERE age > 18;

-- INSERT - вставка новых строк
INSERT INTO users (id, name, email) 
VALUES (1, 'John Doe', 'john@example.com');

-- UPDATE - обновление существующих данных
UPDATE users 
SET age = 25 
WHERE id = 1;

-- DELETE - удаление строк
DELETE FROM users 
WHERE age < 18;

Сравнительная таблица

АспектDDLDML
НазначениеОпределение структуры БДРабота с данными
ПримерыCREATE, ALTER, DROPSELECT, INSERT, UPDATE, DELETE
ЗатрагиваетСхему таблицСодержимое таблиц
ТранзакцииAuto-commit, не откатываютсяПоддерживают ACID
ОткатНельзя откатить (в большинстве БД)Можно откатить (ROLLBACK)
БлокировкиТребуют исключительной блокировкиРабочие блокировки
ПривилегииCREATE, ALTER, DROPSELECT, INSERT, UPDATE, DELETE

Важный момент: TRUNCATE vs DELETE

DELETE (DML)

DELETE FROM users WHERE age < 18;

-- Характеристики DELETE:
-- 1. Можно использовать WHERE
-- 2. Может быть откачена (ROLLBACK)
-- 3. Срабатывают триггеры ON DELETE
-- 4. Медленнее (логирует каждую строку)
-- 5. Не сбрасывает AUTO_INCREMENT

TRUNCATE (DDL)

TRUNCATE TABLE users;

-- Характеристики TRUNCATE:
-- 1. Удаляет ВСЕ строки (нет WHERE)
-- 2. В некоторых БД не откатывается
-- 3. Триггеры ON DELETE НЕ срабатывают
-- 4. Быстрее (удаляет целые страницы)
-- 5. Сбрасывает AUTO_INCREMENT (в большинстве БД)

Применение в Java с ORM

Hibernate/JPA - DDL операции

// Entity определение (DDL в коде)
@Entity
@Table(name = "users", indexes = {
    @Index(name = "idx_email", columnList = "email")
})
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(length = 100, unique = true)
    private String email;
    
    @Column(name = "age", columnDefinition = "INT DEFAULT 0")
    private Integer age;
}

// Hibernate автоматически создаст таблицу на основе entity
// (в зависимости от настройки hibernate.hbm2ddl.auto)

Hibernate properties (управление DDL)

# Автоматические DDL операции при старте приложения
# validate - проверяет соответствие
hibernate.hbm2ddl.auto=validate

# update - обновляет схему, не удаляя данные
hibernate.hbm2ddl.auto=update

# create - создаёт заново (удаляет все данные!)
hibernate.hbm2ddl.auto=create

# create-drop - создаёт при старте, удаляет при остановке
hibernate.hbm2ddl.auto=create-drop

# none - ничего не делает (продакшен)
hibernate.hbm2ddl.auto=none

DML операции с JPA

@Service
@Transactional
public class UserService {
    @Autowired
    private UserRepository userRepository;
    
    // SELECT (DML)
    public User findUser(Long id) {
        return userRepository.findById(id).orElse(null);
    }
    
    // INSERT (DML)
    public User createUser(String name, String email) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        return userRepository.save(user);  // INSERT
    }
    
    // UPDATE (DML)
    public User updateAge(Long id, int age) {
        User user = userRepository.findById(id).orElse(null);
        if (user != null) {
            user.setAge(age);
            return userRepository.save(user);  // UPDATE
        }
        return null;
    }
    
    // DELETE (DML)
    public void deleteUser(Long id) {
        userRepository.deleteById(id);  // DELETE
    }
}

Spring Data JPA - кастомные DML

public interface UserRepository extends JpaRepository<User, Long> {
    // SELECT (DML)
    List<User> findByAge(int age);
    User findByEmail(String email);
    
    // UPDATE (DML) - @Modifying
    @Modifying
    @Query("UPDATE User u SET u.age = :age WHERE u.id = :id")
    int updateAge(@Param("id") Long id, @Param("age") int age);
    
    // DELETE (DML) - @Modifying
    @Modifying
    @Query("DELETE FROM User u WHERE u.age < :age")
    int deleteByAgeBelow(@Param("age") int age);
}

Маиграции (Flyway/Liquibase) - DDL через код

Flyway - SQL миграции

-- V1__Create_users_table.sql (DDL)
CREATE TABLE users (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- V2__Add_age_column.sql (DDL)
ALTER TABLE users ADD COLUMN age INT DEFAULT 0;

-- V3__Insert_initial_data.sql (DML)
INSERT INTO users (name, email, age) 
VALUES ('John Doe', 'john@example.com', 30);

Liquibase - XML миграции

<!-- DDL операция -->
<changeSet id="1" author="dev">
    <createTable tableName="users">
        <column name="id" type="BIGINT" autoIncrement="true">
            <constraints primaryKey="true"/>
        </column>
        <column name="name" type="VARCHAR(100)">
            <constraints nullable="false"/>
        </column>
    </createTable>
</changeSet>

<!-- DML операция -->
<changeSet id="2" author="dev">
    <insert tableName="users">
        <column name="name" value="John Doe"/>
        <column name="email" value="john@example.com"/>
    </insert>
</changeSet>

Ключевые моменты

DDL операции:

  1. Изменяют структуру БД
  2. Как правило не откатываются (auto-commit)
  3. Требуют исключительной блокировки таблиц
  4. Могут быть медленными на больших таблицах
  5. Требуют администраторских привилегий

DML операции:

  1. Изменяют данные в таблицах
  2. Откатываются (ROLLBACK в транзакции)
  3. Используют рабочие блокировки
  4. Оборачиваются в транзакции (ACID)
  5. Требуют SELECT/INSERT/UPDATE/DELETE привилегий

На практике:

  • Продакшн: TRUNCATE опаснее DELETE (нельзя откатить)
  • Миграции: DDL отделяют от DML
  • ORM: скрывает различия, но нужно понимать, что происходит
  • Индексы: CREATE INDEX - это DDL, но нет данных
  • Откат: DML откатывается, DDL часто нет