티스토리 뷰
데이터베이스란?
- 데이터베이스: 관련성을 가지며 중복이 없는 데이터들의 집합.
- DBMS(DataBase Management System): 데이터베이스를 관리하는 시스템(데이터베이스 관리 시스템)
- RDBMS(Relation DBMS): 관계형 DBMS. SQL이라는 언어를 사용해 데이터 를 관리함.
대표적인 RDBMS로 Oracle, MySQL, MSSQL 등이 있습니다. RDBMS에서 데이터를 관리하려면 SQL을 사용합니다.
맥 MySQL 설치
- HomeBerew 설치
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
- HomeBrew를 이용해 MySQL 설치
brew install mysql
brew services start mysql
mysql_secure_installation
- MySQL 접속
mysql -h localhost -u root -p
데이터베이스 및 테이블 생성하기
데이터베이스 생성하기
`CREATE SCHEMA [데이터베이스명] 옵션` 명령어를 이용해 데이터베이스를 생성할 수 있습니다. MySQL에서 데이터베이스와 스키마는 같은 개념입니다.
- `DEFAULT CHARACTER SET utf8mb4`: 스키마 내에서 생성되는 모든 테이블과 열에 대해 기본 문자 집합을 utf8mb4로 설정합니다.
- `DEFAULT COLLATE utf8mb4_general_ci`: `COLLATE`는 해당 `CHARACTER SET`을 어떤 형식으로 정렬할지를 의미합니다. 기본 정렬 규칙(collation)을 utf8mb4_general_ci로 설정합니다.
CREATE SCHEMA `nodejs` DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_general_ci;
테이블 생성하기
`CREATE TABLE [데이터베이스 명.테이블 명]`명령어를 사용해 테이블을 생성합니다.
컬럼의 자료형
- `INT`: 정수를 의미합니다.
- `VARCHAR(자릿수)`: 자릿수만큼의 문자열을 넣을수 있습니다.
- `TEXT`: 긴글을 저장할 때 사용합니다. 수백 자 이내의 문자열은 보통 VARCHAR로 많이 처리하고, 그보다 길면 TEXT로 처리합니다.
- `TINYINT`: -128부터 127까지의 정수를 저장할 때 사용합니다.
- `DATETIME`: 날짜와 시간에 대한 정보를 담고 있습니다.
옵션
- `NULL`/`NOT NULL`: 빈칸을 허용할지 여부를 묻는 옵션입니다.
- `AUTO_INCREMENT`: 숫자를 저절로 올리는 옵션입니다. id컬럼은 기본으로 설정되어 있습니다.
- `UNSIGEND`: 숫자 자료형에 적용되는 옵션입니다. 숫자 자료형은 기본적으로 음수 범위를 지원합니다.
- `ZERO FILL`: 비어있는 자리에 모두 0을 넣습니다. 숫자 의 자릿수가 조덩되어 있을 때 사용할 수 있습니다.
- `DEFAULT 값`: 데이터베이스 저장 시 해당 컬럼에 값이 없을 떄 MySQL이 기본값을 대신 넣습니다.
- `PRIMARY KEY`: 해당 컬럼을 기본키로 지정합니다.
- `UNIQUE INDEX`: 해당 값이 고유해야 하는지에 대한 옵션입니다. `PRIMARY KEY`는 자동으로 `UNIQUE INDEX`를 포함합니다.
CREATE TABLE nodejs.users (
id INT NOT NULL AUTO_INCREMENT,
name VARCHR(20) NOT NULL,
age INT UNSIGNED NOT NULL,
married TINYINT NOT NULL,
comment TEXT NULL,
created_at DATETIME NOT NULL DEFAULT now(),
PRIMARY KEY(id),
UNIQUE INDEX name_UNIQUE (name ASC))
COMMENT = '사용자 정보'
ENGINE = InnoDB;
만들어진 테이블 확인하기
`DESC 테이블명` 명령어를 사용해 만들어진 테이블을 확인합니다.
DESC users;
만들어진 테이블 삭제하기
`DROP TABLE [테이블명]` 명령어를 사용해 만들어진 테이블을 삭제합니다.
DROP TABLE users;
외래키를 가지는 테이블 생성하기
다른 테이블의 기본키를 저장하는 컬럼을 외래 키(foreign key)라고 합니다. `CCONSTRAINT [제약조건명] FOREIGN KEY [컬럼명] REFERENCES [참고하는 컬럼명]`으로 외래 키를 지정할 수 있습니다.
`ON UPDATE`와 `ON DELETE`를 `CASCADE`로 설정하면 참고하는 부모 테이블 데이터가 수정되거나 삭제되면 그것과 연결된 자식 테이블도 같이 수정하거나 삭제합니다.
CREATE TABLE nodejs.comments (
id INT NOT NULL AUTO_INCREMENT,
commenter INT NOT NULL,
comment VARCHAR(100) NOT NULL,
created_at DATETIME NOT NULL DEFAULT now(),
PRIMARY KEY(id),
INDEX commenter_idx (commenter ASC),
CONSTRAINT commenter
FOREIGN KEY (commenter)
REFERENCES nodejs.users (id)
ON DELETE CASCADE
ON UPDATE CASCADE)
COMMENT = '댓글'
ENGINE=InnoDB;
만들어진 테이블들을 확인하기
SHOW TABLES;
CRUD 작업하기
Create(생성)
데이터를 생성해 데이터베이스에 넣는 SQL명령어는 `INSERT ONTO [테이블명] ([컬럼1], [컬럼2], ...) VALUES ([값1], [값2], ...)` 입니다.
INSERT INTO nodejs.users (name, age, married, comment) VALUES ('bearn', 26, 0, '자기소개1');
READ(조회)
데이터베이스에 있는 데이터를 조회하는 SQL명령어는 `SELECT * FROM [테이블명]`입니다. 특정 컬럼만 조회하려면 `SELECT` 절 다음에 조회할 컬럼을 넣으면 됩니다. 특정 조건을 가진 데이터만 조회하려면 `WHERE` 절을 사용하면 됩니다. `AND`와 `OR`를 사용해 조건을 줄 수 있습니다.
SELECT name, age FROM nodejs.users WHRE married = 1 AND age > 30;
`ORDER BY [컬럼명] [ASC|DESC]` 키워드를 사용해 정렬이 가능합니다. DESC는 내림차순 ASC는 오름차순입니다.
SELECT id, name FROM nodejs.users ORDER BY age DESC;
`LIMIT [숫자]` 키워드를 이용해 조회할 로우 개수를 설정할 수 있습니다.
SELECT id, name FROM nodejs.users ORDER BY age DESC LIMIT 1;
`OFFSET [건너뛸 숫자]` 키워드를 사용해 로우 개수를 설정하면서 몇 개를 건너 뛸지 설정할 수 있습니다.
SELECT id, name FROM nodejs.users ORDER BY age DESC LIMIT 1 OFFSET 1;
UPDATE(수정)
`UPDATE [테이블명] SET [컬럼명 = 바꿀 값] WHERE [조건]` 명령어를 사용해 데이터에비으세 있는 데이터를 수정할 수 있습니다.
UPDATE nodejs.users SET comment = '바꿀 내용' WHERE id = 2;
DELETE(삭제)
`DELETE FROM [테이블명] WHRE [조건]` 명령어를 사용해 데이터베이스에 있는 데이터를 삭제할 수 있습니다.
DELETE FROM nodejs.users WHERE id = 2;
시퀄라이즈 사용하기
- ORM(Object-realational Mapping): 객체와 데이터에비스의 릴레이션을 매핑해주는 도구
- 시퀄라이즈: 자바스크립트 ORM
시퀄라이즈를 이용하면 SQL을 직접 사용하지 않고도 자바스크립트 만으로 MySQL을 조작할 수 있습니다.
프로젝트 설정
- sequelize-cli: 시퀄라이즈 명령어를 실행하기 위한 패키지입니다.
- mysql2: MySQL과 시퀄라이즈를 이어주는 드라이버입니다. mysql2 자체는 데이터베이스 프로그램이 아닙니다.
npm install sequelize sequelize-cli mysql2
시퀄라이즈 초기화
npx sequelize-cli init
MySQL 연결 설정
MySQL과 연동할 때는 `config`폴더 안의`config/config.json` 정보가 사용됩니다.
{
"development": {
"username": "root",
"password": "password",
"database": "database_development",
"host": "127.0.0.1",
"dialect": "mysql"
}
}
모델 정의하기
- `models/User.js`
const Sequelize = require("sequelize");
class User extends Sequelize.Model {
static initiate(sequelize) {
User.init(
{
name: {
type: Sequelize.STRING(20),
allowNull: false,
unique: true,
},
age: {
type: Sequelize.INTEGER.UNSIGNED,
allowNull: false,
},
married: {
type: Sequelize.BOOLEAN,
allowNull: false,
},
comment: {
type: Sequelize.TEXT,
allowNull: true,
},
created_at: {
type: Sequelize.DATE,
allowNull: false,
defaultValue: Sequelize.NOW,
},
},
{
sequelize,
timestamps: false,
underscored: false,
modelName: "User",
tableName: "users",
paranoid: false,
charset: "utf8",
collate: "utf8_general_ci",
}
);
}
static associate(db) {
db.User.hasMany(db.Comment, { foreignKey: "commenter", sourceKey: "id" });
}
}
module.exports = User;
- `models/comment.js`
const Sequelize = require("sequelize");
class Comment extends Sequelize.Model {
static initiate(sequelize) {
Comment.init(
{
comment: {
type: Sequelize.STRING(100),
allowNull: false,
},
created_at: {
type: Sequelize.DATE,
allowNull: true,
defaultValue: Sequelize.NOW,
},
},
{
sequelize,
timestamps: false,
modelName: "Comment",
tableName: "comments",
paranoid: false,
charset: "utf8mb4",
collate: "utf8mb4_general_ci",
}
);
}
static associate(db) {
db.Comment.belongsTo(db.User, { foreignKey: "commenter", targetKey: "id" });
}
}
module.exports = Comment;
- `models/index.js`
`Sequelize`는 시퀄라이즈 패키지이자 생성자입니다. `config/config.json`에서 데이터베이스 설정을 불러온 후 `new Sequelize`를 통해 MySQL 연결 객체를 생성합니다. 연결 객체를 나중에 재사용하기 위해 `db.sequelize`에 넣어놓습니다. 앞으로 `db`객체를 `require`해서 `User`와`Comment` 모델에 접근할 수 있습니다. `모델.init`이 실행되어야 테이블이 모델로 연결됩니다. `모델.associate`을 실행하면 다른 테이블과의 관계를 연결합니다.
const Sequelize = require("sequelize");
const User = require("./user");
const Comment = require("./comment");
const env = process.env.NODE_ENV || "development";
const config = require(__dirname + "/../config/config.json")[env];
const db = {};
const sequelize = new Sequelize(
config.database,
config.username,
config.password,
config
);
db.sequelize = sequelize;
db.User = User;
db.Comment = Comment;
User.initiate(sequelize);
Comment.initiate(sequelize);
User.associate(db);
Comment.associate(db);
module.exports = db;
모델 관계 정의
일대다 (One-to-Many) 관계
User.hasMany(Comment);
Comment.belongsTo(User);
일대일 (One-to-One) 관계
User.hasOne(Info);
Info.belongsTo(User);
다대다 (Many-to-Many) 관계
Post.belongsToMany(Hashtag);
Hashtag.belongsToMany(Post);
쿼리 알아보기
- 테이블의 모든 데이터를 조회
// SELECT * FROM nodejs.users;
User.findAll({});
- 테이블 데이터에서 원하는 컬럼만 조회
// SELECT name, age FROM nodejs.users;
User.findAll({
attributes:['name', 'married'],
});
- where 조건 나열
// SELECT name, age FROM nodejs.users WHERE married = 1 AND age > 30;
User.findAll({
attrubutes:['name', 'age'],
where:{
married: true,
age: { [Op.gt]: 30 },
}
});
- `OFFSET` 과 `LIMIT` 설정
// SELECT id, name FROM users ORDER BY age DESC LIMIT 1 OFFSET 1;
User.findAll({
attributes: ['id', 'name'],
order: ['age', 'DESC'],
limit: 1,
offset: 1,
});
- 로우를 수정
// UPDATE nodejs.users SET comment = '바꿀 내용' WHERE id = 2;
User.update({
comment: '바꿀 내용',
}, {
where: {id:2},
});
- 로우를 삭제
// DELETE FROM nodejs.users WHERE id = 2;
User.destroy({
where: { id: 2 },
});
관계 쿼리
- 조회
const user = await User.findOne({
include: [{
model: Comment,
}]
});
console.log(user.Comments); // 사용자 댓글
const user = await User.findOne({});
const comments = await user.getComments();
console.log(user.Comments); // 사용자 댓글
- 생성
const user = await User.findOne({});
const comment = await Comment.create();
await user.addComment(comment);
// 또는
await user.addComment(comment.id);
- 여러개 추가
const user = await User.findOne({});
const comment1 = await Comment.create();
const comment2 = await Comment.create();
await user.addComment([comment1, comment2]);
시퀄라이즈로 SQL 쿼리하기
const [result, metadata] = await sequelize.query('SELECT * from comments');
console.log(result);
참고
'Node.js' 카테고리의 다른 글
JS로 차트 훼손 없이 엑셀 수정하기!!! (1) | 2024.11.16 |
---|---|
[Node.js 교과서] 섹션 8 - 몽고디비 (0) | 2024.11.11 |
[Node.js 교과서] 섹션 6 - 익스프레스 웹 서버 만들기 (0) | 2024.11.03 |
[Node.js 교과서] 섹션 5 - 패키지 매니저 (1) | 2024.10.25 |
[Node.js 교과서] 섹션 4 - http 모듈로 서버 만들기 (1) | 2024.10.23 |