💡 용어 설명:
데이터 무결성: 데이터의 정확성과 일관성을 유지하는 특성.
💡 SQL: 데이터베이스와 대화하는 언어로, 데이터를 조회, 삽입, 수정, 삭제하는 명령어를 사용한다.
StudentID | Name | Major | Year |
---|---|---|---|
101 | Alice Johnson | Computer Science | 3 |
102 | Bob Smith | Mathematics | 2 |
103 | Charlie Brown | Physics | 4 |
CourseID | CourseName | Credits |
---|---|---|
201 | Data Structures | 4 |
202 | Linear Algebra | 3 |
203 | Quantum Mechanics | 4 |
EnrollmentID | StudentID | CourseID | Grade |
---|---|---|---|
1 | 101 | 201 | A |
2 | 102 | 202 | B+ |
3 | 103 | 203 | A- |
💡 Primary Key(기본 키): 각 테이블에서 행을 고유하게 식별하는 열. 예: students 테이블의 StudentID.
Foreign Key(외래 키): 다른 테이블의 Primary Key를 참조하여 테이블 간 관계를 정의. 예: enrollments 테이블의 StudentID는 students 테이블의 StudentID를 참조.
{
"StudentID": 101,
"Name": "Alice Johnson",
"Major": "Computer Science",
"Year": 3,
"Courses": [
{
"CourseID": 201,
"CourseName": "Data Structures",
"Grade": "A"
},
{
"CourseID": 202,
"CourseName": "Linear Algebra",
"Grade": "B+"
}
]
}
{
"students": {
"101": {
"name": "Alice Johnson",
"major": "Computer Science",
"year": 3
},
"102": {
"name": "Bob Smith",
"major": "Mathematics",
"year": 2
}
},
"courses": {
"201": {
"name": "Data Structures",
"credits": 4
},
"202": {
"name": "Linear Algebra",
"credits": 3
}
}
}
💡 특징:
- 데이터를 중첩 형태로 저장하여 여러 관련 데이터를 한 번의 쿼리로 가져올 수 있음.
- 관계형 데이터베이스와 달리 복잡한 조인 없이 데이터를 간단하게 처리.
구분 | 관계형 데이터베이스 (RDB) | 비관계형 데이터베이스 (NoSQL) |
---|---|---|
데이터 구조 | 정형화된 테이블 구조 (행과 열) | 유연한 데이터 구조 (문서, 키-값, 그래프 등) |
스키마 | 고정된 스키마 필요 | 스키마가 없거나 유연 |
데이터 관계 | 테이블 간 관계 정의 | 데이터 간 관계가 없거나 간접적 |
확장성 | 수직적 확장 | 수평적 확장 |
데이터 처리 속도 | 복잡한 조건에서 효율적 처리 | 단순한 데이터 검색에 빠름 |
사용 사례 | 금융, ERP, 전자상거래 등 | 빅데이터, IoT, 실시간 처리 시스템 등 |
구분 | 관계형 데이터베이스 (RDB) | 비관계형 데이터베이스 (NoSQL) |
---|---|---|
데이터 구조 | 테이블 기반 | 문서, 키-값, 그래프 등 |
확장성 | 수직적 확장 | 수평적 확장 |
데이터 처리 속도 | 복잡한 쿼리에 효율적 | 빠른 읽기 및 쓰기 |
CDN(Content Delivery Network)
에서 이미지를 빠르게 로드할 수 있다.Storage
서비스는 이미지 저장 및 전송에 특화되어 있으며, CDN을 제공하여 빠른 데이터 전송을 보장한다.텍스트 기반 메타데이터 관리
에 집중하고, 이미지는 스토리지를 통해 관리된다.코드 예제
import { supabase } from "../supabase/supabaseClient";
import { v4 as uuidv4 } from "uuid";
export const uploadImage = async (file) => {
try {
// 이미지 업로드
const { data: storageData, error: uploadError } = await supabase.storage
.from("images")
.upload(`uploads/${uuidv4()}.png`, file);
if (uploadError) {
throw new Error(uploadError.message);
}
// 공개 URL 가져오기
const { data: publicUrlData } = supabase.storage
.from("images")
.getPublicUrl(storageData.path);
return publicUrlData.publicUrl;
} catch (error) {
console.error("Error uploading image:", error);
throw error;
}
};
활용 예시
bcrypt
, SHA-256
.Salt
)을 추가하여 해싱하면 동일한 비밀번호라도 서로 다른 해시 값이 생성된다.bcrypt
는 해싱과 솔팅을 자동으로 처리하여 안전하다.auth.signUp
또는 auth.signIn
메서드를 호출한다.
// 1. 회원가입 함수 (auth.signUp)
export const signUp = async (email, password) => {
try {
// Supabase auth.signUp 호출
const { data, error } = await supabase.auth.signUp({
email,
password,
});
if (error) {
throw new Error(`회원가입 실패: ${error.message}`);
}
console.log("회원가입 성공:", data);
return data;
} catch (err) {
console.error(err.message);
return null;
}
};
// 2. 로그인 함수 (auth.signInWithPassword)
export const signIn = async (email, password) => {
try {
const { data, error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) {
throw new Error(`로그인 실패: ${error.message}`);
}
console.log("로그인 성공:", data);
return data;
} catch (err) {
console.error(err.message);
return null;
}
};
// 3. 토큰을 이용한 API 요청
export const getUserProfile = async () => {
try {
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
throw new Error("로그인된 사용자가 없습니다.");
}
const { data, error } = await supabase
.from("profiles")
.select("*")
.eq("user_id", session.user.id);
if (error) {
throw new Error(`프로필 가져오기 실패: ${error.message}`);
}
console.log("사용자 프로필:", data);
return data;
} catch (err) {
console.error(err.message);
return null;
}
};
signUp
함수가 호출된다.signIn
함수가 호출되고, 인증 세션 정보가 로컬 스토리지에 저장된다.getUserProfile
함수를 호출하여 세션 정보를 기반으로 데이터에 접근한다.auth.users
테이블만 사용한다.join
이 어려워, 다른 테이블과 사용자 정보를 결합하기 어렵다.auth.users
: 인증 정보(이메일, 비밀번호) 저장.users
테이블: 프로필 정보(닉네임, 생년월일 등) 저장.join
쿼리 활용 가능하고 사용자 프로필 정보를 유연하게 관리할 수 있다.
export const signUp = async ({ email, password, displayName }) => {
try {
const { user, error: authError } = await supabase.auth.signUp({
email,
password,
});
if (authError) {
throw new Error(authError.message);
}
const { data: profileData, error: profileError } = await supabase
.from("users")
.insert({ id: user.id, displayName });
if (profileError) {
throw new Error(profileError.message);
}
return profileData;
} catch (error) {
console.error("Error during sign-up:", error);
throw error;
}
};
auth.users
만 사용하거나, users
테이블을 추가로 사용하여 관리할 수 있다.