作为后端工程师,我们经常负责构建可以扩展和处理大量资源、用户和实体的系统,每个资源、用户和实体都需要唯一的标识。在许多情况下,使用顺序 ID(例如 1、2、3)似乎是一个简单的解决方案,但随着应用程序在分布式系统中增长和扩展,这很快就会成为问题。这就是UUID(通用唯一标识符)发挥作用的地方。
在这篇博文中,我们将探讨:
UUID(通用唯一标识符)是一个 128 位数字,用于唯一标识计算机系统中的信息。它被设计为全局唯一,这意味着在不同系统中独立生成的 UUID 不会发生冲突。
UUID 如下所示:
66e69275-c6bc-800c-90a6-2f41cb991502
由 32 个十六进制数字组成,分五组显示,用连字符分隔,格式为 8-4-4-4-12。
分布式系统中的数据库密钥:在不同数据库或微服务需要生成唯一ID而不互相通信的系统中,UUID确保唯一性。例如,在分布式电子商务平台中,每个服务可能独立生成订单或交易 ID,UUID 将避免任何冲突。
会话 ID:UUID 通常用于标识 Web 应用程序中的用户会话。当您需要维护会话信息而不泄露敏感或可预测数据时,它们特别有用。
文件或资源标识符:当您需要跨不同平台或数据库跟踪文件、文档或任何资源时,可以为每个资源分配一个 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,这是 Web 开发中最常见的变体。
使用 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,确保每个用户都有一个唯一的标识符,即使跨分布式数据库,也不会与其他记录冲突。
忽略 UUID 而选择顺序或自动递增 ID 可能会带来多种风险:
安全漏洞:序列 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中文网其他相关文章!