← 返回蜂巢洞察

在模型查看医学图像之前和之后,这些图像会发生哪些变化?

医学影像领域的论文中充斥着一些看起来很熟悉的术语:标准化、标签标注、验证、注释以及预处理。 如果你有机器学习的背景,你可能会认为自己已经理解这些术语的含义了。有时候确实如此。 但医学影像领域有一些特殊的之处。有些术语的含义有所不同,而有些术语则会根据具体的使用场景而有不同的用法。 本文将以一张胸部X光片为例,从它被拍摄下来的那一刻开始,一直讲到模型做出预测的整个过程。在这个过程中,我们将了解在医学影像论文中常见的那些术语以及它们真正的含义。 还有一个配套的 笔记本 ,你可以利用它亲自尝试完成这些步骤,而不仅仅是阅读相关内容而已。 我们将涵盖的内容: 你将学到的知识 从图像到数据集 1. 数据采

医学影像领域的论文中充斥着一些看起来很熟悉的术语:标准化、标签标注、验证、注释以及预处理。

如果你有机器学习的背景,你可能会认为自己已经理解这些术语的含义了。有时候确实如此。

但医学影像领域有一些特殊的之处。有些术语的含义有所不同,而有些术语则会根据具体的使用场景而有不同的用法。

本文将以一张胸部X光片为例,从它被拍摄下来的那一刻开始,一直讲到模型做出预测的整个过程。在这个过程中,我们将了解在医学影像论文中常见的那些术语以及它们真正的含义。

还有一个配套的笔记本,你可以利用它亲自尝试完成这些步骤,而不仅仅是阅读相关内容而已。

我们将涵盖的内容:

你将学到的知识

  • 医学影像处理流程中每个阶段的名称,以及每个阶段实际发生的具体操作

  • 匿名化、去标识化和假名化之间的区别

  • 为什么“注释”和“标准化”在不同语境下会具有不同的含义

  • 在同一张图像上,分类、检测与分割这些技术之间有何差异

  • 标准化协调能解决什么问题,以及为什么验证方案的设计比模型选择本身更为重要

从图像到数据集

1. 数据采集

数据采集是指生成图像的过程,这一过程涉及成像设备、其设置以及患者摆放的姿势等因素。

如果使用不同的设备进行拍摄,同一患者的两张胸部X光片可能会呈现不同的效果。设备的制造商、探测器类型、曝光设置以及图像处理软件都会影响最终生成的图像质量。

患者的体位同样非常重要。例如,站立状态下拍摄的后前位胸部X光片,与患者躺在床上时拍摄的前后位X光片相比,结果可能会大相径庭。

其中一个重要的差异在于心脏在图像中的显示大小,这一因素会直接影响模型学习到的信息。

这些相关信息大多存储在DICOM文件中。

DICOM(医学数字成像与通信标准)是一种用于存储和传输医疗图像的标准格式。一个DICOM文件不仅包含像素数据,还记录了患者信息、扫描设备信息、检查项目详情、图像方向、像素间距等其他重要参数。

本教程中使用的示例图像最初是以JPEG格式保存的,因此原始的临床DICOM元数据并不可用。为了便于演示,我们使用Python代码将这张图像重新封装到了一个新的DICOM文件中,并添加了一些有用的字段。

ds = pydicom.dcmread("synthetic_cxr.dcm")

for tag in ["Modality", "BodyPartExamined", "ViewPosition",
            "Manufacturer", "ManufacturerModelName", "KVP", "PixelSpacing"]:
    print(f"{tag:24s} {ds[tag].value}")

其中一个值得关注的字段是像素间距。这个参数表示每个像素所代表的实际物理尺寸,通常以毫米为单位。即使两张图像的像素数量相同(都是512×512像素),它们所覆盖的实际面积也可能不同。

因此,如果你想用毫米为单位来测量某个对象的尺寸,就不能仅仅数像素的数量,还需要知道像素间距这个参数。

2. 匿名化、去标识化和假名化

这三个术语经常被混用,但实际上它们具有不同的含义。

去标识化

去标识化是指删除或修改那些可能用于识别个人身份的信息。

例如:

患者姓名
医疗记录编号
出生日期
电话号码
其他身份识别信息

这样做的目的是降低数据被关联到具体个人的概率。

假名化

假名化是指用代码来替代原有的标识符。

例如:

Jane Doe → SUBJ_0041

需要注意的是,通过一个单独的键仍然可以将SUBJ_0041与Jane Doe对应起来。

医院有时需要使用这种假名化技术,因为它们可能需要重新找到原始的患者信息。

匿名化

匿名化的目的在于使重新识别这些数据变得不再可行。

与假名化不同,匿名化过程中不会保留任何可以用来将数据与特定个人关联起来的关键信息。

一个简单的问题可以帮助我们判断:

是否可以通过其他额外信息将这些数据再次与特定个人联系起来?

如果答案是“可以”,因为存在某种关键信息可以将数据与个人重新关联起来,那么通常这种情况属于假名化,而不是真正的匿名化。

这些术语的具体法律含义因国家及相关法规而异,因此研究人员在使用这些术语时应当格外谨慎。

像素中也可能包含识别信息

仅从DICOM头部中删除信息仅仅只是整个匿名化流程的一部分。

有时,文本实际上会被直接绘制到图像中。

患者姓名
日期
医院名称
R
便携式设备

这种现象被称为“嵌入式注释”。

仅仅删除DICOM元数据并不能消除这些文本;必须从图像中的像素中直接找出这些文本并将其移除。

这其实比听起来要困难得多。例如,仅仅依靠“寻找图像顶部的亮色像素”这样的简单规则,并不能准确识别出所有文本——锁骨和肋骨等骨骼结构也会呈现亮色。

胸部X光片上同时显示了识别信息和解剖结构,这一例子说明了为什么仅通过删除DICOM元数据是无法彻底去除嵌入式注释的。

因此,一个真正的去标识化流程通常会结合多种技术来实现:

文本检测
光学字符识别
图像区域规则分析
DICOM元数据删除
验证

我们的目标不仅仅是去除文本,还要确保这些文本确实已经被彻底移除。

IDENTIFIERS = [
    "患者姓名",
    "患者ID",
    "患者出生日期",
    "患者性别",
    "医疗机构名称",
    "转诊医生姓名",
    "检查日期",
    "检查时间",
    "数据访问编号"
]

for tag in IDENTIFIERS:
    if tag in ds:
        ds[tag].value = ""

# 用于记录是否已经执行了去标识化操作。
# 单凭这个字段并不能使整个数据集达到去标识化的效果。
ds.PatientIdentityRemoved = "YES"

在像素级别进行处理时,简单的演示与实际的生产流程会存在很大差异。

3. 安全港规则与专家判定

如果你从事与美国医疗数据相关的工作,那么你经常会遇到两个HIPAA相关的术语:安全港规则专家判定

这两种方法都是用来确定受保护的医疗信息是否已经按照HIPAA的规定完成了去标识化处理的。

安全港规则

“安全港规则”其实是一份检查清单。根据这一规则,需要删除18类标识信息,这些信息包括:

姓名、
面积小于一个州的地理信息、
某些具体日期、
电话号码、
医疗记录编号、
设备识别码、
全貌照片等。

遵循这份清单进行操作相对简单直接。

专家评估机制

“专家评估机制”采用另一种处理方式。由具备资质的专家来评估信息被重新识别所带来的风险,并详细说明为何剩余的风险非常小。这样一来,研究人员就可以保留那些根据“安全港规则”本应删除的信息。

例如,在研究某种疾病随时间的变化趋势时,具体的日期信息会非常有用。

因此,这里存在一种权衡:

“安全港规则”更为简单,但限制也更多;

而专家评估机制则更具灵活性,但需要提供书面的风险评估报告。

这些都是美国的HIPAA法规中规定的内容。其他国家的隐私法律和规定也有所不同。

比如欧盟的GDPR以及印度的DPDP法案,对于匿名数据和假名数据有着各自的处理方式。

从数据集到模型输入

4. 预处理

预处理是指在将图像输入模型之前对其进行的各种处理操作。

常见的预处理步骤包括:

  • 调整图像大小

  • 设置显示窗口范围

  • 改变图像的方向

  • 对像素值进行标准化处理

预处理前后胸部X光片的对比,展示了尺寸调整、窗口设置及方向变化等处理效果。

调整图像大小

大多数模型都要求输入尺寸固定的图像。而医学影像的尺寸往往各不相同,因此人们通常会先对它们进行尺寸调整。

不过,调整图像大小会改变像素与实际物理空间之间的对应关系。

例如,如果将一张图像的尺寸从1024×1024调整为512×512,那么每个像素所代表的实际面积就会发生变化。

因此,当需要获取以毫米为单位的实际距离或面积等数值时,就必须考虑原始图像的像素间距或调整后的像素间距。

设置显示窗口范围

“设置显示窗口范围”是指选择一定范围内的亮度值,并将这些值映射到显示屏上。超出这个范围的值会被裁剪掉。

放射科医生在查看CT图像时,经常会使用不同的窗口设置,因为不同的组织在不同的窗口设置下会更易于被观察到。

设置显示窗口范围只会改变图像的显示效果,并不会改变原始图像数据本身。

这个示例代码演示了如何使用第2和第98百分位数来设置显示窗口范围。

lo, hi = np.percentile(img, [2, 98])
windowed = np.clip(
    (img.astype(float) - lo) / (hi - lo),
    0,
    1
)

方向性

医学影像中也包含有关方向的信息。如果这些信息被弄错,就会导致左右方向颠倒,而对于胸部X光片来说,这是一个非常严重的错误。

5. 规范化

这里有一个具有双重含义的概念。

胸部X光片,展示了不同的像素值规范化方法,对比了原始图像以及经过最小-最大值规范化和Z分数标准化的图像。
  • 最小-最大值规范化:通过重新调整数值范围,使最低值变为0,最高值变为1。
f = img.astype(np.float32)

minmax = (f - f.min()) / (f.max() - f.min())
  • Z分数规范化:先减去平均值,再除以标准差,这样得到的数值的平均值就是0,标准差就是1。

    zscore = (f - f.mean()) / f.std()

最小-最大值规范化的缺点在于它直接依赖于数据中的最小值和最大值。例如,某些非常亮的像素(可能是由于设备故障或噪声引起的),可能会改变整个数值范围,从而导致图像中大部分数据的分布被压缩到较小的范围内。

Z分数规范化对最小值和最大值的依赖性较低,但极端值仍然可能影响平均值和标准差的结果。

在医学影像处理中,规范化也可以应用于不同的图像或数据集;不过,要让来自不同设备或机构的图像具有可比性,这种操作更准确地应该被称为协调统一。当需要处理多个来源的图像时,这种区分就显得尤为重要了,具体内容将在第10节中进行说明。

6. 注释与标签

这两者都用于描述与图像相关的信息,但它们所代表的含义是不同的。

胸部X光片,展示了图像级标签与空间注释之间的区别,图中标出了肺部区域。

标签通常用于描述整张图像的内容。

图像 → 肺炎

注释则主要用于指出图像中特定对象的具体位置。

<它有可能是:

  • 边界框

  • 多边形

  • 等高线

  • 像素级掩膜

例如:

图像 → 肺部掩膜

关键的区别在于位置

标签只能告诉你图像中有什么,而注释则能同时告诉你有什么以及位于哪里

创建注释也需要耗费更多的精力。

一个大型数据集中可能包含从放射报告中提取的数百万个图像级标签,但只有其中一小部分会由临床医生生成详细的掩膜。

这种简化方法也有其代价。一份报告可能会诊断出“肺炎”,但这并不一定能准确指出哪些像素属于肺炎区域。这种情况会导致标签信息不准确

7. 数据集分割

在医学影像研究中,最重要的决策之一就是如何划分数据

数据的分割通常应该在患者层面进行,而不是在图像层面。

假设一名患者有五张X光片。如果将其中三张用于训练,两张用于测试,那么模型在训练过程中就已经见过该患者的这些影像了。患者特有的特征可能会同时出现在这两组数据中。这就是一种数据泄露现象。

同样的原则也适用于以下情况:

  • 同一患者的多次扫描结果

  • 同一研究中的多张图像

  • 从同一原始扫描中生成的多张图像

目标很简单:测试集应该包含模型在训练过程中未曾见过的患者数据。

因此,不要这样做:

先分割图像再分配患者信息

而应该这样做:

先划分患者群体,再为它们分别分配对应的图像

这种细节对最终结果的影响,有时甚至比改变模型架构还要大。

从模型到预测

8. 分类、检测与分割

以同一张胸部X光片为例,我们可以提出三个不同的问题。

胸部X光片,显示三种模型输出结果:图像级分类标签、用于检测的边界框以及像素级分割掩膜。

分类

患者是否患有肺炎?

模型会返回一个标签或概率值。

肺炎:0.92

它只能告诉你图像中有什么,而无法指出具体位置。

检测

异常部位在哪里?模型会返回一个边界框。

[x, y, width, height]

它只能告诉你病变大致位于什么位置,而无法描述其确切的形状。

分割

哪些像素属于异常区域呢?

模型会返回一个像素级别的掩码,这样你就能知道病变的形状和位置了。

一个简单的记忆方法:

分类 = 是什么?

检测 = 在哪里?

分割 = 哪些像素属于异常区域?

一般来说,从分类到检测再到分割,所需的标注工作量会逐渐增加。

因此,请选择最能解决你需求的任务。如果你只需要知道某次扫描结果是否异常,那么可能就不需要进行图像分割了。

9. 数据增强

数据增强是通过修改现有图像来创建新的训练样本。

常见的处理方法包括:

  • 旋转

  • 平移

  • 缩放

  • 亮度调整

当医学数据集规模较小时,这种方法会非常有用。

胸部X光片示例,展示了图像增强处理的效果,包括旋转和水平翻转,这些操作会改变图像中的解剖结构方向。

但是,医学图像有一个重要的限制:经过处理的图像必须仍然看起来像是真实患者身上可能出现的景象。

例如,在自然图像机器学习中,水平翻转是一种常见的处理方法。

将一张猫的照片水平翻转过来,得到的仍然是一张猫的图片。

但如果你对一张胸部X光片进行水平翻转,心脏的位置就会发生改变,这样就可能生成一张看起来像“右位心”的图像,即心脏位于身体的右侧。

同样的问题也会出现在标记的处理上。原本位于右侧的标记可能会突然出现在左侧,字母本身也会被镜像处理。模型并不会自动意识到这种变化在解剖学上是错误的。

其他类型的数据增强也可能带来问题。例如,过大的亮度调整可能会掩盖一些重要的病变信息;而过度裁剪图像则可能会丢失部分肺部组织。

因此,在使用任何数据增强技术之前,都要先思考这样一个问题:这样的处理结果是否有可能真实地出现在真实的患者身上? 如果不能,那就不要使用这种技术。
# 合理的例子:小幅旋转
M = cv2.getRotationMatrix2D((cx, cy), 7, 1.0)
rotated = cv2.warpAffine(
    img,
    M,
    (w, h),
    borderMode=cv2.BORDER_REPLICATE
)

# 对于胸部X光片来说,这种处理方法可能存在问题:
flipped = img[:, ::-1]

10. 后处理

后处理是在模型生成输出结果之后进行的。

分割模型通常会为每个像素提供一个概率值。在应用阈值进行二值化处理后,得到的掩码中可能会包含一些不需要的小区域或孔洞。

经过后处理前后,肺部分割掩膜的变化情况,可见小连接区域被移除,空洞也被填充了。

例如,该笔记本中原始的掩膜包含以下内容:

  • 两个较大的肺部区域

  • 十四个不需要的小区域

一个常见的处理步骤就是只保留最大的连通组件。

由于我们预期存在两个肺部,因此可以保留那两个最大的区域;同时也可以填充那些小空洞。

labelled, n = ndimage.label(mask > 0)

sizes = ndimage.sum(
    mask > 0,
    labelled,
    range(1, n + 1)
)

keep = np.isin(
    labelled,
    np.argsort(sizes)[-2:] + 1
)

clean = ndimage.binary_fill_holes(keep)

在这个例子中,经过处理后,连通组件的数量从16个减少到了2个,但只有不到5%的像素发生了变化。

这说明了评估时一个重要的点:即使预测结果的结构发生了显著变化,像素重叠程度的数值也可能几乎保持不变。

对于某些应用来说,连通区域的数量和形状比像素重叠程度的微小变化更为重要。因此,应该选择那些能够反映你真正关心的误差指标来进行评估。

另外,在进行后处理时也要格外小心。如果你的模型在得到理想的结果之前需要经过大量的处理步骤,那么这些处理过程可能会掩盖模型中存在的一些问题。

无论如何,都一定要查看原始的输出结果。

从一家医院到现实世界

11. 统一性处理

假设有两家医院使用不同的扫描设备。

这些设备的图像在以下方面可能存在差异:

  • 亮度

  • 对比度

  • 噪声水平

  • 分辨率

  • 图像处理方式

如果一个模型主要是在医院A的数据上训练的,那么它可能会学会这些差异,而不是那些与疾病相关的特征。因此,这个模型在医院A的表现可能很好,但在医院B却可能表现不佳。

这时,统一性处理就能起到帮助作用了。

不同成像设备拍摄的胸部X光片在经过统一性处理前后的对比,可以看出亮度与对比度的差异。

统一性处理的目的是使来自不同设备的数据更具可比性,同时保留那些重要的信息。

一个简单的例子就是直方图匹配

通过这种技术,可以调整某张图像的像素值分布,使其更接近参考图像的风格。

from skimage.exposure import match_histograms

harmonized = matchHistograms(
    image_from_hospital_b,
    reference_from_hospital_a
)

这种方法有助于解决亮度与对比度方面的差异,但并不能解决所有问题。

如果两台扫描设备的分辨率、噪声特性或图像处理流程不同,仅依靠直方图匹配是远远不够的。

此外,如果在图像采集或后续处理过程中丢失了某些信息,那么任何优化措施也无法神奇地恢复这些数据。

一个有用的经验法则是:

标准化处理可以使数值更加一致。

协调机制则用于解决不同数据源之间的系统性差异。

12. 回顾性研究与前瞻性研究

这一部分主要讨论研究设计的相关内容。

回顾性研究

回顾性研究是利用已有的数据进行的。

例如:

我们从医院档案中收集了4,000张胸部X光片,并用它们来测试我们的模型。

在医学人工智能领域,这种研究方法较为常见,因为它的实施速度较快且成本较低。

然而,这种方法也容易产生偏见。研究人员在决定哪些患者应被纳入研究、使用哪些医院的数据、以及设定什么样的阈值时,都可能无意中影响研究结果。

这些决策有时会使得研究结果看起来更加理想化。

前瞻性研究

在前瞻性研究中,研究人员首先制定研究计划,然后才开始收集数据。

例如:

在收集图像之前,我们会明确研究对象、评估标准以及成功指标。

这种做法可以减少某些偏见的发生,因为重要的决策是在看到研究结果之前就已经做出的。

外部验证

你还会遇到“外部验证”这个术语。

所谓外部验证,就是用与模型开发过程中使用的数据无关的数据来测试该模型。

例如:

医院A → 模型训练
医院A → 内部测试
医院B → 外部验证

一种更严格的验证方法可能是:

医院A + B → 模型开发
医院C → 外部验证

如果一个模型在某家医院的数据上表现良好,但在另一家医院的表现却很差,那很可能是因为该模型掌握了特定医院的特殊规律,而非疾病的普遍特征。

因此,外部验证通常比仅仅从同一数据集中随机抽取部分数据进行验证要更有参考价值。

总结

现在,请看下面这段来自某篇医学影像研究论文的示例:

我们回顾性地收集了来自两家机构的4,120张去标识化的胸部X光片。这些图像被重新采样为512×512像素大小,然后进行了强度标准化处理,并通过直方图匹配实现了不同机构数据之间的协调统一。肺部区域由两位放射科医生手动标注,分割结果则通过最大成分选取算法进行了后期处理。最后,我们在第三家医院的890例病例上对该模型进行了外部验证。

那段文字包含了大量信息,但现在你可以理解其中的内容了:

  1. 回顾性收集的数据:研究人员使用了已经存在的图像。

  2. 去标识化处理:图像中的识别信息被删除或进行了修改。

  3. 数据来源于多个机构:这个数据集来自不止一个来源。

  4. 图像尺寸调整为512×512:所有图像都被转换成了统一的尺寸。

  5. 强度值进行了标准化处理:像素值被转换为更加统一的数值范围。

  6. 数据进行了协调统一:研究人员努力消除两个研究地点之间的系统性差异。

  7. 由两位放射科医生手动标注:专家们标注出了肺部区域的具体位置。

  8. 后续进行了后处理:模型输出的原始分割结果经过了进一步整理。

  9. 在独立数据上进行了外部验证:该模型在另一个地点的独立数据上接受了测试。

最后这一点尤为重要。一个仅在开发时使用的数据集上表现良好的模型,其实并不能很好地反映它在现实世界中的性能。

结论

一篇医学影像研究论文往往只需用短短几句话就能描述整个数据处理流程。

一旦你理解了相关的专业术语,你就可以以不同的方式来解读这些内容。

你不应该仅仅关注模型本身及其准确率,而应该思考以下这些问题:

  • 这些图像是从哪里获取的?

  • 使用了哪种扫描设备?

  • 在训练数据和测试数据中,患者是否被分开处理?

  • 识别信息是如何被去除的?

  • 图像中是否存在无法清除的文字信息?

  • 标签或注释是由谁创建的?

  • 进行了哪些预处理步骤?

  • 像素值是如何被标准化的?

  • 不同医院或使用的扫描设备的数据是否经过了协调统一?

  • 该模型是否在独立数据上接受了验证?

  • 测试数据是否真正具有独立性?

  • 模型在进行预测后的输出结果发生了什么变化?

模型只不过是医学影像处理流程中的一个环节而已。实际上,许多更为重要的问题往往出现在模型甚至还没有看到任何图像之前

相关文章

技术实践

每位开发人员都应该了解的关于产品数据追踪的相关知识

产品数据记录了您的应用程序或网站内部实际发生的情况。它展示了用户的行为、系统的运行状态,以及业务的运营表现。 在本文中,您将了解什么是产品数据、哪些部分值得追踪、哪些部分可以忽略不计,同时也会明白:编写代码的开发者实际上承担着比他人认为的更大的责任。 目录 什么是产品数据? 为什么应该追踪产品数据? 还有谁会使用您所追踪的数据? 为什么应该尽早开始数据追踪? 为什么数据追踪永无止境? 在您的产品中应该追踪哪些内容? 有哪些内容是不应该被追踪的? 如何安全地处理用户数据? 总结 什么是产品数据? 产品数据指的是您的应用程序或网站内部实际发生的情况。它能够回答一些简单的问题:用户喜欢哪些功能?他们

阅读全文
技术实践

从数据到价值:通过一个实际应用案例来理解数据管理[完整书籍]

如今,数据已成为一种极其宝贵的资源。它使企业能够在市场中展开竞争,并推动创新,从而提升所提供产品与服务的质量。 数据处理能让团队自动化各种流程。它还能辅助决策制定,为终端用户带来更加个性化的体验,在诸如银行欺诈防范或风险控制等诸多领域帮助人们发现其中的规律。企业必须明白如何以有效、安全且合法的方式收集和利用数据。 你很可能目前正在使用或曾经使用过各种各样的产品与服务。你也知道,那些涉及数据的流程几乎与我们身边的所有事物都息息相关。此外,你或许已经熟悉“大数据”、“数据分析”、“人工智能”以及“机器学习”这些术语了。 但除非你是这些领域中的专家,否则其中一些概念可能会让你感到难以理解。毕竟,这些

阅读全文
技术实践

如何使用MONAI在超声数据上训练肿瘤分割模型

大多数分割教程都是从选择一个模型开始,将图像输入该模型中,然后调整超参数直到相关指标得到改善。但这种方法忽略了通常最为关键的一步:理解数据本身。 在本教程中,我们首先会对数据集进行详细分析,随后会根据这些分析结果来决定MONAI分割流程中的每一个设计细节。 我们将涵盖以下内容: 本教程适合谁? 关于数据集 什么是MONAI,为什么使用它? 什么是Dice评分? 第1部分——建模前的数据分析 类别平衡对分割结果的影响 患者数量对数据划分的影响 第2部分——构建分割流程 单一配置对象 按患者分组的数据划分方式 由快照自动选择的转换操作 模型、损失函数与评估指标 结果解读 预测结果可视化 失败模式比

阅读全文
技术实践

布隆过滤器解析:这种概率数据结构是如何为Instagram、谷歌以及各种大规模系统提供支持的

Instagram拥有超过5亿个注册用户名。当有新用户尝试注册时,平台几乎需要立即回答一个问题:这个用户名是否已经被别人使用了? 一种简单的解决方法是进行数据库查询——从用户表中查找该用户名,判断它是否存在。这种方法在数据量较小时效果不错,但当数据库记录数量达到5亿条,且每天要被查询数百万次时,就会成为一个严重的性能瓶颈。即使为数据库添加了索引,每次注册尝试时,数据库仍然需要执行复杂的操作。 幸运的是,还有更聪明的解决方法。在触碰数据库之前,可以先询问另一个系统来快速获取答案。这个系统会给出两种可能的回答: 肯定没有被占用: 这个结论是绝对可靠的,没有任何例外情况。这意味着该用户名是可以使用的

阅读全文