[{"data":1,"prerenderedAt":954},["ShallowReactive",2],{"note:cs\u002Fdb\u002F100+70\u002FDay12-数据库70题-综合62-71":3},{"id":4,"title":5,"body":6,"description":16,"extension":948,"meta":949,"navigation":414,"path":950,"seo":951,"stem":952,"__hash__":953},"notes\u002Fsource\u002Fcs\u002Fdb\u002F100+70\u002FDay12-数据库70题-综合62-71.md","Day 12 - 数据库70题：综合题 62-71",{"type":7,"value":8,"toc":935},"minimark",[9,13,17,22,25,28,31,35,37,40,43,47,49,52,76,79,83,85,88,102,105,109,111,114,128,131,135,137,140,143,158,161,165,167,175,178,186,189,193,196,199,255,258,288,291,360,362,541,544,587,602,604,611,685,688,692,695,751,753,774,777,858,861,922,931],[10,11,5],"h1",{"id":12},"day-12-数据库70题综合题-62-71",[14,15,16],"p",{},"参考重点：教材第 5 章完整性，第 11 章恢复技术，第 12 章并发控制。SQL 均按 SQL Server 写法。",[18,19,21],"h2",{"id":20},"_62-什么是数据库的转储转储的意义是什么","62. 什么是数据库的转储？转储的意义是什么？",[14,23,24],{},"答案：",[14,26,27],{},"数据库转储是把数据库复制到后援存储介质上，形成后援副本的过程。意义是在数据库遭到破坏，尤其是发生介质故障时，可用后援副本和日志文件恢复数据库。",[14,29,30],{},"讲解：转储是恢复的基础。静态转储简单但影响业务；动态转储允许业务运行，但必须配合日志保证一致性。",[18,32,34],{"id":33},"_63-为什么要建立日志文件","63. 为什么要建立日志文件？",[14,36,24],{},[14,38,39],{},"日志文件记录事务对数据库的更新操作，是事务故障和系统故障恢复的依据。通过日志可以撤销未提交事务、重做已提交事务，并配合检查点提高恢复效率。",[14,41,42],{},"讲解：日志通常记录事务标识、操作类型、数据对象、旧值、新值等。必须遵守先写日志原则：数据页写盘前，相应日志先写入稳定存储。",[18,44,46],{"id":45},"_64-怎样进行系统故障的恢复","64. 怎样进行系统故障的恢复？",[14,48,24],{},[14,50,51],{},"系统故障恢复一般步骤：",[53,54,55,59,67,73],"ol",{},[56,57,58],"li",{},"从最近检查点开始扫描日志。",[56,60,61,62,66],{},"找出故障时已经提交但可能未完全写盘的事务，执行 ",[63,64,65],"code",{},"REDO","。",[56,68,69,70,66],{},"找出故障时尚未提交的事务，执行 ",[63,71,72],{},"UNDO",[56,74,75],{},"恢复结束后数据库回到一致状态。",[14,77,78],{},"讲解：系统故障不破坏外存数据库文件，但会丢失内存缓冲区内容。因此既可能需要重做提交事务，也可能需要撤销未提交事务。",[18,80,82],{"id":81},"_65-怎样进行介质故障的恢复","65. 怎样进行介质故障的恢复？",[14,84,24],{},[14,86,87],{},"介质故障恢复一般步骤：",[53,89,90,93,96,99],{},[56,91,92],{},"更换或修复故障介质。",[56,94,95],{},"装入最近一次数据库后援副本。",[56,97,98],{},"利用转储以来的日志文件，重做已经提交的事务。",[56,100,101],{},"必要时撤销未提交事务，使数据库达到一致状态。",[14,103,104],{},"讲解：介质故障会损坏外存数据，因此仅靠日志不够，必须先有数据库备份作为恢复起点。",[18,106,108],{"id":107},"_66-数据库在运行过程可能产生的故障有哪几类","66. 数据库在运行过程可能产生的故障有哪几类？",[14,110,24],{},[14,112,113],{},"常见故障包括：",[53,115,116,119,122,125],{},[56,117,118],{},"事务故障。",[56,120,121],{},"系统故障。",[56,123,124],{},"介质故障。",[56,126,127],{},"计算机病毒、恶意破坏或灾难性故障。",[14,129,130],{},"讲解：不同故障需要不同恢复策略。事务故障通常 UNDO 即可；系统故障需要 UNDO\u002FREDO；介质故障需要备份和日志。",[18,132,134],{"id":133},"_67-叙述数据库的并发控制","67. 叙述数据库的并发控制。",[14,136,24],{},[14,138,139],{},"数据库并发控制是 DBMS 对多个事务同时访问同一数据的操作进行调度和协调，使并发执行结果等价于某个串行执行结果，从而保持数据库一致性。",[14,141,142],{},"常用方法：",[144,145,146,149,152,155],"ul",{},[56,147,148],{},"封锁机制和两段锁协议。",[56,150,151],{},"时间戳排序。",[56,153,154],{},"多版本并发控制（MVCC）。",[56,156,157],{},"设置事务隔离级别。",[14,159,160],{},"讲解：并发控制的目标不是消灭并发，而是在高并发和正确性之间平衡。教材重点是封锁、封锁协议、可串行化和死锁处理。",[18,162,164],{"id":163},"_68-在数据库保护中安全性和完整性有何区别","68. 在数据库保护中，安全性和完整性有何区别？",[14,166,24],{},[144,168,169,172],{},[56,170,171],{},"安全性：保护数据库免受非法访问、非法使用、泄露或破坏。",[56,173,174],{},"完整性：保证数据库中的数据正确、有效、相容，符合语义约束。",[14,176,177],{},"例子：",[144,179,180,183],{},[56,181,182],{},"用户没有权限查看成绩表却试图查询，这是安全性问题。",[56,184,185],{},"成绩被写成 150 分，这是完整性问题。",[14,187,188],{},"讲解：安全性管“谁能做”，完整性管“做出来的数据是否合法”。",[18,190,192],{"id":191},"_69-设数据库含-scd-三个关系表使用-sql-server-设置各个表操作之间的完整性约束","69. 设数据库含 S、C、D 三个关系表，使用 SQL Server 设置各个表操作之间的完整性约束。",[14,194,195],{},"题面关系：",[14,197,198],{},"S",[200,201,202,218],"table",{},[203,204,205],"thead",{},[206,207,208,212,215],"tr",{},[209,210,211],"th",{},"学号",[209,213,214],{},"姓名",[209,216,217],{},"班号",[219,220,221,233,244],"tbody",{},[206,222,223,227,230],{},[224,225,226],"td",{},"S2",[224,228,229],{},"王华",[224,231,232],{},"98001",[206,234,235,238,241],{},[224,236,237],{},"S6",[224,239,240],{},"李英",[224,242,243],{},"98002",[206,245,246,249,252],{},[224,247,248],{},"S12",[224,250,251],{},"刘强",[224,253,254],{},"98003",[14,256,257],{},"C",[200,259,260,270],{},[203,261,262],{},[206,263,264,267],{},[209,265,266],{},"课程号",[209,268,269],{},"课程名称",[219,271,272,280],{},[206,273,274,277],{},[224,275,276],{},"K1",[224,278,279],{},"英语",[206,281,282,285],{},[224,283,284],{},"K12",[224,286,287],{},"高等数学",[14,289,290],{},"D",[200,292,293,304],{},[203,294,295],{},[206,296,297,299,301],{},[209,298,211],{},[209,300,266],{},[209,302,303],{},"分数",[219,305,306,315,324,333,342,351],{},[206,307,308,310,312],{},[224,309,226],{},[224,311,276],{},[224,313,314],{},"84",[206,316,317,319,321],{},[224,318,237],{},[224,320,276],{},[224,322,323],{},"79",[206,325,326,328,330],{},[224,327,248],{},[224,329,276],{},[224,331,332],{},"95",[206,334,335,337,339],{},[224,336,226],{},[224,338,284],{},[224,340,341],{},"91",[206,343,344,346,348],{},[224,345,237],{},[224,347,284],{},[224,349,350],{},"82",[206,352,353,355,357],{},[224,354,248],{},[224,356,284],{},[224,358,359],{},"67",[14,361,24],{},[363,364,369],"pre",{"className":365,"code":366,"language":367,"meta":368,"style":368},"language-sql shiki shiki-themes github-light github-dark","CREATE TABLE dbo.S (\n    学号 varchar(20) NOT NULL,\n    姓名 nvarchar(50) NOT NULL,\n    班号 varchar(20) NOT NULL,\n    CONSTRAINT PK_S PRIMARY KEY (学号)\n);\n\nCREATE TABLE dbo.C (\n    课程号 varchar(20) NOT NULL,\n    课程名称 nvarchar(100) NOT NULL,\n    CONSTRAINT PK_C PRIMARY KEY (课程号),\n    CONSTRAINT UQ_C_课程名称 UNIQUE (课程名称)\n);\n\nCREATE TABLE dbo.D (\n    学号 varchar(20) NOT NULL,\n    课程号 varchar(20) NOT NULL,\n    分数 decimal(5, 2) NULL,\n    CONSTRAINT PK_D PRIMARY KEY (学号, 课程号),\n    CONSTRAINT FK_D_S FOREIGN KEY (学号)\n        REFERENCES dbo.S(学号)\n        ON UPDATE CASCADE\n        ON DELETE NO ACTION,\n    CONSTRAINT FK_D_C FOREIGN KEY (课程号)\n        REFERENCES dbo.C(课程号)\n        ON UPDATE CASCADE\n        ON DELETE NO ACTION,\n    CONSTRAINT CK_D_分数 CHECK (分数 BETWEEN 0 AND 100)\n);\n","sql","",[63,370,371,379,385,391,397,403,409,416,422,428,434,440,446,451,456,462,467,472,478,484,490,496,502,508,514,520,525,530,536],{"__ignoreMap":368},[372,373,376],"span",{"class":374,"line":375},"line",1,[372,377,378],{},"CREATE TABLE dbo.S (\n",[372,380,382],{"class":374,"line":381},2,[372,383,384],{},"    学号 varchar(20) NOT NULL,\n",[372,386,388],{"class":374,"line":387},3,[372,389,390],{},"    姓名 nvarchar(50) NOT NULL,\n",[372,392,394],{"class":374,"line":393},4,[372,395,396],{},"    班号 varchar(20) NOT NULL,\n",[372,398,400],{"class":374,"line":399},5,[372,401,402],{},"    CONSTRAINT PK_S PRIMARY KEY (学号)\n",[372,404,406],{"class":374,"line":405},6,[372,407,408],{},");\n",[372,410,412],{"class":374,"line":411},7,[372,413,415],{"emptyLinePlaceholder":414},true,"\n",[372,417,419],{"class":374,"line":418},8,[372,420,421],{},"CREATE TABLE dbo.C (\n",[372,423,425],{"class":374,"line":424},9,[372,426,427],{},"    课程号 varchar(20) NOT NULL,\n",[372,429,431],{"class":374,"line":430},10,[372,432,433],{},"    课程名称 nvarchar(100) NOT NULL,\n",[372,435,437],{"class":374,"line":436},11,[372,438,439],{},"    CONSTRAINT PK_C PRIMARY KEY (课程号),\n",[372,441,443],{"class":374,"line":442},12,[372,444,445],{},"    CONSTRAINT UQ_C_课程名称 UNIQUE (课程名称)\n",[372,447,449],{"class":374,"line":448},13,[372,450,408],{},[372,452,454],{"class":374,"line":453},14,[372,455,415],{"emptyLinePlaceholder":414},[372,457,459],{"class":374,"line":458},15,[372,460,461],{},"CREATE TABLE dbo.D (\n",[372,463,465],{"class":374,"line":464},16,[372,466,384],{},[372,468,470],{"class":374,"line":469},17,[372,471,427],{},[372,473,475],{"class":374,"line":474},18,[372,476,477],{},"    分数 decimal(5, 2) NULL,\n",[372,479,481],{"class":374,"line":480},19,[372,482,483],{},"    CONSTRAINT PK_D PRIMARY KEY (学号, 课程号),\n",[372,485,487],{"class":374,"line":486},20,[372,488,489],{},"    CONSTRAINT FK_D_S FOREIGN KEY (学号)\n",[372,491,493],{"class":374,"line":492},21,[372,494,495],{},"        REFERENCES dbo.S(学号)\n",[372,497,499],{"class":374,"line":498},22,[372,500,501],{},"        ON UPDATE CASCADE\n",[372,503,505],{"class":374,"line":504},23,[372,506,507],{},"        ON DELETE NO ACTION,\n",[372,509,511],{"class":374,"line":510},24,[372,512,513],{},"    CONSTRAINT FK_D_C FOREIGN KEY (课程号)\n",[372,515,517],{"class":374,"line":516},25,[372,518,519],{},"        REFERENCES dbo.C(课程号)\n",[372,521,523],{"class":374,"line":522},26,[372,524,501],{},[372,526,528],{"class":374,"line":527},27,[372,529,507],{},[372,531,533],{"class":374,"line":532},28,[372,534,535],{},"    CONSTRAINT CK_D_分数 CHECK (分数 BETWEEN 0 AND 100)\n",[372,537,539],{"class":374,"line":538},29,[372,540,408],{},[14,542,543],{},"讲解：",[144,545,546,556,562,572,578],{},[56,547,548,551,552,555],{},[63,549,550],{},"S.学号"," 和 ",[63,553,554],{},"C.课程号"," 是实体完整性。",[56,557,558,561],{},[63,559,560],{},"D(学号, 课程号)"," 是选课表组合主键，保证同一学生同一课程只有一条成绩。",[56,563,564,567,568,571],{},[63,565,566],{},"D.学号","、",[63,569,570],{},"D.课程号"," 是外键，保证参照完整性。",[56,573,574,577],{},[63,575,576],{},"CHECK"," 保证用户定义完整性。",[56,579,580,583,584,66],{},[63,581,582],{},"ON DELETE NO ACTION"," 表示有选课记录时不能随便删除学生或课程；如果业务要求删除学生时同步删除成绩，可改成 ",[63,585,586],{},"ON DELETE CASCADE",[18,588,590,591,594,595,594,598,601],{"id":589},"_70-设有三个事务-t1t2-和-t3动作分别为t1-aa2t2-aa2t3-aa2假定这三个事务允许并行操作讨论它们可能实施的调度","70. 设有三个事务 T1、T2 和 T3，动作分别为：",[63,592,593],{},"T1: A=A+2","，",[63,596,597],{},"T2: A=A*2",[63,599,600],{},"T3: A=A**2","。假定这三个事务允许并行操作，讨论它们可能实施的调度。",[14,603,24],{},[14,605,606,607,610],{},"若要求正确并发，调度结果应等价于某个串行调度。设初值为 ",[63,608,609],{},"A=a","，三个事务的 6 种串行顺序结果为：",[200,612,613,623],{},[203,614,615],{},[206,616,617,620],{},[209,618,619],{},"串行顺序",[209,621,622],{},"最终结果",[219,624,625,635,645,655,665,675],{},[206,626,627,630],{},[224,628,629],{},"T1 -> T2 -> T3",[224,631,632],{},[63,633,634],{},"((a + 2) * 2)^2",[206,636,637,640],{},[224,638,639],{},"T1 -> T3 -> T2",[224,641,642],{},[63,643,644],{},"(a + 2)^2 * 2",[206,646,647,650],{},[224,648,649],{},"T2 -> T1 -> T3",[224,651,652],{},[63,653,654],{},"(2a + 2)^2",[206,656,657,660],{},[224,658,659],{},"T2 -> T3 -> T1",[224,661,662],{},[63,663,664],{},"(2a)^2 + 2",[206,666,667,670],{},[224,668,669],{},"T3 -> T1 -> T2",[224,671,672],{},[63,673,674],{},"(a^2 + 2) * 2",[206,676,677,680],{},[224,678,679],{},"T3 -> T2 -> T1",[224,681,682],{},[63,683,684],{},"2a^2 + 2",[14,686,687],{},"讲解：这三个操作都读写同一数据 A，彼此不交换顺序。例如先加 2 再乘 2，与先乘 2 再加 2 结果不同。因此正确调度必须可串行化。实际系统中可让每个事务对 A 加 X 锁并保持到提交，这样并发执行会退化为某个串行顺序，但结果正确。",[18,689,691],{"id":690},"_71-假设存款余额-x1000-元甲事务取走-300-元乙事务取走-200-元执行时间如下如何实现这两个事务的并发控制","71. 假设存款余额 X=1000 元，甲事务取走 300 元，乙事务取走 200 元，执行时间如下。如何实现这两个事务的并发控制？",[14,693,694],{},"题面调度：",[200,696,697,710],{},[203,698,699],{},[206,700,701,704,707],{},[209,702,703],{},"甲事务",[209,705,706],{},"时间",[209,708,709],{},"乙事务",[219,711,712,722,731,741],{},[206,713,714,717,720],{},[224,715,716],{},"读 X",[224,718,719],{},"T1",[224,721],{},[206,723,724,726,729],{},[224,725],{},[224,727,728],{},"T2",[224,730,716],{},[206,732,733,736,739],{},[224,734,735],{},"更新 X=X-300",[224,737,738],{},"T3",[224,740],{},[206,742,743,745,748],{},[224,744],{},[224,746,747],{},"T4",[224,749,750],{},"更新 X=X-200",[14,752,24],{},[14,754,755,756,759,760,763,764,767,768,770,771,66],{},"该调度会产生丢失修改。甲、乙都读到 ",[63,757,758],{},"X=1000","，甲写回 ",[63,761,762],{},"700","，乙再按旧值写回 ",[63,765,766],{},"800","，最终余额可能为 ",[63,769,766],{},"，甲的取款被覆盖；正确结果应为 ",[63,772,773],{},"500",[14,775,776],{},"可用排他锁或可串行化事务控制：",[363,778,780],{"className":365,"code":779,"language":367,"meta":368,"style":368},"-- 甲事务\nBEGIN TRANSACTION;\n\nUPDATE dbo.Accounts\nSET Balance = Balance - 300\nWHERE AccountNo = 'X';\n\nCOMMIT TRANSACTION;\n\n-- 乙事务\nBEGIN TRANSACTION;\n\nUPDATE dbo.Accounts\nSET Balance = Balance - 200\nWHERE AccountNo = 'X';\n\nCOMMIT TRANSACTION;\n",[63,781,782,787,792,796,801,806,811,815,820,824,829,833,837,841,846,850,854],{"__ignoreMap":368},[372,783,784],{"class":374,"line":375},[372,785,786],{},"-- 甲事务\n",[372,788,789],{"class":374,"line":381},[372,790,791],{},"BEGIN TRANSACTION;\n",[372,793,794],{"class":374,"line":387},[372,795,415],{"emptyLinePlaceholder":414},[372,797,798],{"class":374,"line":393},[372,799,800],{},"UPDATE dbo.Accounts\n",[372,802,803],{"class":374,"line":399},[372,804,805],{},"SET Balance = Balance - 300\n",[372,807,808],{"class":374,"line":405},[372,809,810],{},"WHERE AccountNo = 'X';\n",[372,812,813],{"class":374,"line":411},[372,814,415],{"emptyLinePlaceholder":414},[372,816,817],{"class":374,"line":418},[372,818,819],{},"COMMIT TRANSACTION;\n",[372,821,822],{"class":374,"line":424},[372,823,415],{"emptyLinePlaceholder":414},[372,825,826],{"class":374,"line":430},[372,827,828],{},"-- 乙事务\n",[372,830,831],{"class":374,"line":436},[372,832,791],{},[372,834,835],{"class":374,"line":442},[372,836,415],{"emptyLinePlaceholder":414},[372,838,839],{"class":374,"line":448},[372,840,800],{},[372,842,843],{"class":374,"line":453},[372,844,845],{},"SET Balance = Balance - 200\n",[372,847,848],{"class":374,"line":458},[372,849,810],{},[372,851,852],{"class":374,"line":464},[372,853,415],{"emptyLinePlaceholder":414},[372,855,856],{"class":374,"line":469},[372,857,819],{},[14,859,860],{},"若必须先读再算，可在 SQL Server 中使用更新锁和保持锁：",[363,862,864],{"className":365,"code":863,"language":367,"meta":368,"style":368},"BEGIN TRANSACTION;\n\nDECLARE @x decimal(12, 2);\n\nSELECT @x = Balance\nFROM dbo.Accounts WITH (UPDLOCK, HOLDLOCK)\nWHERE AccountNo = 'X';\n\nUPDATE dbo.Accounts\nSET Balance = @x - 300\nWHERE AccountNo = 'X';\n\nCOMMIT TRANSACTION;\n",[63,865,866,870,874,879,883,888,893,897,901,905,910,914,918],{"__ignoreMap":368},[372,867,868],{"class":374,"line":375},[372,869,791],{},[372,871,872],{"class":374,"line":381},[372,873,415],{"emptyLinePlaceholder":414},[372,875,876],{"class":374,"line":387},[372,877,878],{},"DECLARE @x decimal(12, 2);\n",[372,880,881],{"class":374,"line":393},[372,882,415],{"emptyLinePlaceholder":414},[372,884,885],{"class":374,"line":399},[372,886,887],{},"SELECT @x = Balance\n",[372,889,890],{"class":374,"line":405},[372,891,892],{},"FROM dbo.Accounts WITH (UPDLOCK, HOLDLOCK)\n",[372,894,895],{"class":374,"line":411},[372,896,810],{},[372,898,899],{"class":374,"line":418},[372,900,415],{"emptyLinePlaceholder":414},[372,902,903],{"class":374,"line":424},[372,904,800],{},[372,906,907],{"class":374,"line":430},[372,908,909],{},"SET Balance = @x - 300\n",[372,911,912],{"class":374,"line":436},[372,913,810],{},[372,915,916],{"class":374,"line":442},[372,917,415],{"emptyLinePlaceholder":414},[372,919,920],{"class":374,"line":448},[372,921,819],{},[14,923,543,924,927,928,66],{},[63,925,926],{},"UPDLOCK, HOLDLOCK"," 使事务在读取余额时就锁住该行，并保持到事务结束，另一个事务必须等待。这样两个取款事务按某个串行顺序执行，最终余额为 ",[63,929,930],{},"1000 - 300 - 200 = 500",[932,933,934],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":368,"searchDepth":381,"depth":381,"links":936},[937,938,939,940,941,942,943,944,945,947],{"id":20,"depth":381,"text":21},{"id":33,"depth":381,"text":34},{"id":45,"depth":381,"text":46},{"id":81,"depth":381,"text":82},{"id":107,"depth":381,"text":108},{"id":133,"depth":381,"text":134},{"id":163,"depth":381,"text":164},{"id":191,"depth":381,"text":192},{"id":589,"depth":381,"text":946},"70. 设有三个事务 T1、T2 和 T3，动作分别为：T1: A=A+2，T2: A=A*2，T3: A=A**2。假定这三个事务允许并行操作，讨论它们可能实施的调度。",{"id":690,"depth":381,"text":691},"md",{},"\u002Fsource\u002Fcs\u002Fdb\u002F100+70\u002Fday12-70-62-71",{"title":5,"description":16},"source\u002Fcs\u002Fdb\u002F100+70\u002FDay12-数据库70题-综合62-71","GeGDc6JLOkFxvzSukHx0Wvk32gJiKAN-WgQolTb2tdo",1793692175132]