백엔드 엔지니어로서 우리는 각각 고유한 식별이 필요한 수많은 리소스, 사용자 및 엔터티를 확장하고 처리할 수 있는 시스템을 구축하는 임무를 맡는 경우가 많습니다. 대부분의 경우 순차 ID(예: 1, 2, 3)를 사용하는 것은 간단한 해결책처럼 보이지만 애플리케이션이 분산 시스템 전체에서 성장하고 확장되면 문제가 될 수 있습니다. 이것이 UUID(Universally Unique Identifier)가 들어오는 곳입니다.
이 블로그 게시물에서 살펴볼 내용은 다음과 같습니다.
UUID(Universally Unique Identifier)는 컴퓨터 시스템에서 정보를 고유하게 식별하는 데 사용되는 128비트 숫자입니다. 전역적으로 고유하도록 설계되었습니다. 즉, 서로 다른 시스템에서 독립적으로 생성된 UUID가 충돌하지 않습니다.
UUID는 다음과 같습니다.
66e69275-c6bc-800c-90a6-2f41cb991502
32개의 16진수 숫자로 구성되며 8-4-4-4-12 형식으로 하이픈으로 구분된 5개 그룹으로 표시됩니다.
분산 시스템의 데이터베이스 키: 서로 다른 데이터베이스나 마이크로서비스가 서로 통신하지 않고 고유 ID를 생성해야 하는 시스템에서 UUID는 고유성을 보장합니다. 예를 들어 분산 전자 상거래 플랫폼에서 각 서비스는 독립적으로 주문 또는 거래 ID를 생성할 수 있으며 UUID는 충돌을 방지합니다.
세션 ID: UUID는 일반적으로 웹 애플리케이션에서 사용자 세션을 식별하는 데 사용됩니다. 민감하거나 예측 가능한 데이터를 유출하지 않고 세션 정보를 유지해야 할 때 특히 유용합니다.
파일 또는 리소스 식별자: 다양한 플랫폼이나 데이터베이스에서 파일, 문서 또는 리소스를 추적해야 하는 경우 UUID를 각 리소스에 할당하여 위험 없이 쉽게 조회할 수 있습니다. 중복되었습니다.
API 및 외부 참조: API에 순차적이거나 쉽게 추측할 수 있는 ID(예: user/1, user/2)를 노출하면 개인 정보 보호 취약성이 발생할 수 있습니다. UUID(예: user/66e69275-c6bc-800c-90a6-2f41cb991502)를 사용하면 사용자가 자신에게 속하지 않은 리소스를 추측하고 액세스할 가능성이 줄어듭니다.
Python의 uuid 라이브러리를 사용하면 UUID를 쉽게 생성하고 관리할 수 있습니다. 방법은 다음과 같습니다.
import uuid # Generate a UUID generated_uuid = uuid.uuid4() print(f"Generated UUID: {generated_uuid}")
uuid4() 함수는 웹 개발에서 가장 일반적으로 사용되는 변형인 난수 또는 의사 난수를 기반으로 임의의 UUID를 생성합니다.
PostgreSQL과 같은 데이터베이스를 사용할 때는 UUID를 기본 키로 사용하는 것이 일반적입니다. SQLAlchemy를 사용하여 Python에서 이를 설정하는 방법은 다음과 같습니다.
from sqlalchemy import Column, String from sqlalchemy.dialects.postgresql import UUID import uuid from sqlalchemy.ext.declarative import declarative_base Base = declarative_base() class User(Base): __tablename__ = 'users' id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, unique=True, nullable=False) username = Column(String, nullable=False) # This will generate a UUID primary key for each new user.
이 예에서는 id 필드를 UUID로 정의하여 각 사용자가 분산 데이터베이스에서도 다른 레코드와 충돌하지 않는 고유 식별자를 갖도록 보장합니다.
순차 또는 자동 증가 ID를 선호하여 UUID를 무시하면 여러 가지 위험이 발생할 수 있습니다.
보안 취약점: 순차 ID는 예측 가능하므로 공격자가 쉽게 기록을 열거하고 민감한 데이터를 발견할 수 있습니다. 예를 들어 사용자 ID가 순차적인 경우 공격자는 다른 사용자 ID를 추측하여 승인되지 않은 계정에 액세스하려고 시도할 수 있습니다.
데이터 충돌: 분산 시스템에서 자동 증가 정수에 의존하면 ID 충돌이 발생할 수 있으며, 특히 여러 서비스나 데이터베이스가 중앙 조정 없이 ID를 생성하는 경우 더욱 그렇습니다.
데이터 마이그레이션 및 병합 문제: 데이터베이스를 결합하거나 시스템 간에 데이터를 마이그레이션할 때 고유하지 않은 순차 ID를 사용하면 충돌이 발생할 수 있습니다. UUID는 고유성을 보장하여 이러한 문제를 방지합니다.
UUID를 문자열로 저장: 일반적인 실수는 UUID를 문자열로 저장하는 것입니다. 이는 특히 대규모 데이터베이스에서 공간을 낭비하고 쿼리 속도를 저하시킬 수 있습니다. PostgreSQL과 같은 대부분의 최신 데이터베이스에는 UUID를 효율적으로 저장하는 기본 UUID 유형이 있습니다.
틀림:
CREATE TABLE users ( id VARCHAR(36) PRIMARY KEY );
그렇습니다:
CREATE TABLE users ( id UUID PRIMARY KEY );
Not Using the Correct UUID Version: There are several versions of UUIDs (e.g., uuid1(), uuid3(), uuid4(), uuid5()), each suited to specific use cases. uuid4(), based on random numbers, is the most commonly used for generating unique IDs in web applications. Be mindful of which version you’re using and whether it fits your needs.
Ignoring Collision Possibilities: While UUIDs are designed to be unique, there’s a very small chance of collision. For most applications, the risk is negligible, but if you’re generating billions of UUIDs or operating in highly sensitive environments, you should implement collision detection.
Use UUIDs for External References: When exposing IDs in URLs or APIs, prefer UUIDs to sequential IDs. This enhances security and makes it harder for users to predict resource IDs.
Store UUIDs in Native Formats: Use the database's native UUID type to store UUIDs instead of strings. This reduces storage space and improves query performance.
Choose the Right UUID Version: In most cases, uuid4() (random-based UUID) is the best choice for generating unique identifiers in web applications. However, if you need deterministically generated UUIDs, you might consider uuid3() or uuid5() (namespace-based UUIDs).
Validate UUIDs: When accepting UUIDs from user input, always validate them to ensure they are properly formatted before processing. In Python, you can use UUID objects to check the validity of a string.
def is_valid_uuid(uuid_to_test, version=4): try: uuid_obj = uuid.UUID(uuid_to_test, version=version) return str(uuid_obj) == uuid_to_test except ValueError: return False # Example usage print(is_valid_uuid("66e69275-c6bc-800c-90a6-2f41cb991502")) # True print(is_valid_uuid("invalid-uuid-string")) # False
UUIDs are powerful tools for generating unique identifiers in distributed systems and ensuring security in web applications. They help you avoid issues like data collisions, predictable ID attacks, and ID conflicts during database migrations. By understanding and following best practices for UUIDs, you can build more robust, scalable, and secure backend systems.
Remember to use the appropriate UUID version, store them correctly in your databases, and be mindful of their potential risks. With these tips, you’ll be well-equipped to handle UUIDs effectively in your projects!
Feel free to comment below if you have any questions or additional tips about UUIDs! Happy coding!
위 내용은 UUID 이해: 주니어 개발자를 위한 백엔드 엔지니어 가이드의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!