메인 콘텐츠로 건너뛰기

VillageSQL is a drop-in replacement for MySQL with extensions.

All examples on this page work on VillageSQL. Install Now →
플래그 없이 rails new를 실행하면 개발 환경에서 MySQL이 아니라 SQLite를 얻습니다. Rails 8 애플리케이션을 MySQL로 향하게 하려면 스캐폴딩 시점의 명시적 플래그 하나, 실제 사용자와 호스트를 지정하는 database.yml, 그리고 컴파일에 네이티브 MySQL 클라이언트 라이브러리가 필요한 gem이 필요합니다. 이 가이드는 실제 MySQL 호환 서버에서 이 세 가지를 모두 거치며, 아래의 모든 것이 실제로 실행된 데이터베이스로 VillageSQL을 사용합니다.

스캐폴딩 전에 도구 체인 확인하기

Rails 8에는 Ruby 3.2 이상이 필요합니다. rails new를 실행하기 전에 머신에 무엇이 있는지 확인하세요:
시스템 Ruby만 있는 새 macOS 설치에서는 다음과 같은 결과가 나올 수 있습니다:
Ruby 2.6은 Rails 8을 실행할 수 없습니다. Homebrew로 최신 Ruby를 설치하고 PATH에서 시스템 Ruby보다 앞에 두세요:
이 결과는 ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +PRISM [arm64-darwin25]로, Rails 8의 하한보다 훨씬 높습니다. gem install rails가 무엇으로 해석되든 믿기보다는 버전 제약을 붙여 Rails 자체를 설치하세요:
이것은 Rails 8.1.3.1을 설치했습니다. Rails 8.1은 ~> 8.0 제약을 충족하는데, 그 연산자가 “8.0 이상, 9.0 미만”을 뜻하기 때문입니다.

MySQL 어댑터로 스캐폴딩하기

Rails 8은 MySQL이나 PostgreSQL을 기본값으로 하지 않습니다. rails new --help를 실행하면 실제 기본값이 보입니다:
Rails 8에서도 mysql이 여전히 올바른 값이며, mysql2 gem과 어댑터를 선택합니다. trilogy는 Rails가 역시 지원하는 별도의 순수 Ruby MySQL 프로토콜 어댑터로, 이 가이드가 하는 선택과는 다른 선택입니다. mysql 값으로 앱을 스캐폴딩하세요:
이것은 Gemfile에 mysql2를 쓰고 adapter: mysql2로 미리 설정된 config/database.yml을 생성합니다. --skip-git은 선택 사항이며 앱 디렉터리가 자체 git 저장소가 되지 않을 때만 관련이 있습니다. mysql2 gem에는 네이티브 확장이 있어 컴파일할 때 헤더가 포함된 MySQL 클라이언트 라이브러리가 필요합니다. 없으면 bundle install이 mysql2 단계에서 실패합니다. Homebrew를 쓰는 macOS에서는:
mysql-client는 Homebrew에서 keg-only이므로(전체 mysql 포뮬러와 충돌하기 때문에 /opt/homebrew에 심볼릭 링크되지 않음), PATH에 의존하는 대신 bundle config에 위치를 명시적으로 알려줘야 하는 이유가 바로 그것입니다. 이 설정으로 bundle install은 나머지 Rails 8.1.3.1 의존성 집합과 함께 mysql2 0.5.7을 컴파일하고 설치했습니다.

전용 데이터베이스와 사용자 만들기

새 애플리케이션을 root 계정으로 향하게 하지 마세요. 실행 중인 서버에 데이터베이스와 범위가 제한된 사용자를 만드세요:
rails_app은 localhost가 아니라 127.0.0.1에서의 접근을 허가받았으므로, config/database.yml이 Unix 소켓이 아니라 TCP로 이 사용자를 향하게 하세요:

rails db:create에 실제로 필요한 것

rails db:create는 현재 RAILS_ENV 아래에 지정된 데이터베이스만 만드는 것이 아닙니다. rails_app에 rails_guide.*에 대한 권한만 부여한 상태에서 실행하면 다음과 같은 결과가 나왔습니다:
rails_guide는 성공적으로 만들어졌습니다: GRANT ALL PRIVILEGES ON rails_guide.*는 아직 존재하지 않는 데이터베이스를 만들기에 충분한데, 권한이 기존 객체가 아니라 데이터베이스 이름에 대한 범위로 부여되기 때문입니다. 하지만 rails db:create는 같은 실행에서 test 환경의 데이터베이스도 만들려고 하고, rails_guide_test에는 권한이 부여된 적이 없습니다. 이 태스크는 기본적으로 development와 test 데이터베이스를 둘 다 만들고, production만 제외됩니다. 두 번째 데이터베이스 이름에 권한을 부여하면 해결됩니다:
범위가 제한된 비특권 사용자라도, RAILS_ENV에 지정된 데이터베이스만이 아니라 Rails가 만들려고 하는 모든 데이터베이스 이름에 권한이 부여되어 있다면 rails db:create에 충분합니다. 슈퍼유저나 전역 CREATE 권한은 필요하지 않습니다.

마이그레이션하고 서버에서 직접 확인하기

Post 모델을 생성하고 마이그레이션하세요:
생성된 마이그레이션:
Rails 자체의 마이그레이션 출력을 믿지 말고, 서버에 직접 쿼리해 테이블이 존재하는지 확인하세요:

라우트와 컨트롤러를 연결하고 서버에서 테스트하기

index와 create에 대한 리소스 라우트를 추가하세요:
최소한의 JSON 컨트롤러:
서버를 시작하고 curl로 두 액션을 모두 실행하세요:
HTTP 응답에서 멈추지 마세요. 쓰기가 실제 테이블에 들어갔는지 확인하세요:
ActiveRecord가 보고한 것과 같은 내용의 행이 존재하고, 타임스탬프는 created_at이 mysql2를 통해 올바르게 왕복했음을 확인해 줍니다.

연결 풀 크기와 Puma의 스레드 수는 같은 숫자입니다

Rails 8.1이 생성하는 database.yml은 이전 Rails 버전에서 알던 pool 키를 더 이상 사용하지 않습니다. max_connections를 사용합니다:
pool: 키는 여전히 동작하고 경고도 내지 않습니다: max_connections가 없으면 max_connections는 사용 중단 경로 없이 단순 조회로 그 값으로 대체됩니다. Rails 8.1이 사용 중단한 것은 Ruby 메서드 HashConfig#pool로, 이제 HashConfig#max_connections의 별칭이며, 이는 database.yml 키와는 다른 것입니다. 두 키를 서로 다른 값으로 설정하면 조용히 해결되지 않습니다. 부팅 시 오류를 일으킵니다:
이것이 중요한 이유는 같은 환경 변수가 Puma의 스레드 풀 크기도 정하기 때문입니다. config/puma.rb는 그것을 직접 읽으며, 그렇다고 명시하는 주석이 있습니다:
두 기본값은 같은 숫자가 아닙니다: RAILS_MAX_THREADS가 설정되지 않으면 database.yml은 연결 5개로, puma.rb는 스레드 3개로 대체됩니다. 기본값 그대로 두면 풀에는 Puma가 사용할 스레드보다 많은 연결이 있는데, 이는 안전하지만 약간 낭비입니다. 목표 스레드 수를 알게 되면 RAILS_MAX_THREADS를 명시적으로 설정하세요. 그러면 두 설정이 함께 움직입니다. 풀이 스레드 수보다 작은 쪽이 위험한 방향입니다: 스레드가 빈 연결을 기다리며 줄을 서고, 부하 아래에서는 로그에 설명할 오류 없이 요청 지연으로 나타납니다.

자주 묻는 질문

--database=mysql은 모든 Rails 8 버전에서 같은 gem을 설치하나요?

Rails 8 안에서는 그렇습니다. mysql2 gem과 mysql2 어댑터로 해석되며, Rails 8.1.3.1에서 rails new --help로 확인했습니다. trilogy는 같은 플래그에 대한 별도의 유효한 값입니다: 컴파일할 네이티브 확장이 없는 순수 Ruby MySQL 와이어 프로토콜 클라이언트로, 다른 gem을 사용하는 대가로 mysql-client 헤더 의존성을 없앱니다. 스캐폴딩 시점에 하나를 선택하세요; database.yml과 Gemfile을 건드리지 않고 나중에 바꿔 끼울 수 있는 어댑터가 아닙니다.

rails db:create에는 왜 단순한 CREATE 권한 대신 데이터베이스별 권한이 필요한가요?

MySQL의 GRANT ... ON dbname.* TO user는 dbname이 아직 존재하지 않아도 동작하며, 그 특정 데이터베이스를 만드는 것을 허가합니다. 다른 이름의 데이터베이스를 만드는 것은 허가하지 않습니다. rails db:create는 한 번의 실행에서 config/database.yml의 development와 test 데이터베이스를 둘 다 만들기 때문에, 범위가 제한된 사용자에게는 일상적으로 사용할 환경 하나에 대한 권한이 아니라 각각을 지정하는 권한이 필요합니다.

VillageSQL에서는 순정 MySQL과 다르게 마이그레이션을 실행해야 하나요?

아니요. 이 가이드의 모든 명령, rails db:create, rails db:migrate, rails generate model은 수정 없이 VillageSQL 서버에서 실행되었습니다. VillageSQL은 MySQL의 드롭인 대체품이므로, mysql2와 ActiveRecord의 MySQL 어댑터는 MySQL 자체에서와 같은 와이어 프로토콜과 같은 SHOW/DESCRIBE 출력을 봅니다.

문제 해결

함께 보기