我很感激,如果你可以帮助我在我非常简单的应用程序"中最小化读写次数。我是新手,所以请保持温柔:)
我的应用程序基本上是一个测验, ~120个问题,每页约20页~~ 6个问题全部写入同一个"表" 。根据我的学生回答某些问题的方式,他们将被发送回早期的问题或后续问题的措辞可能会改变。在测验结束时,应用程序会根据正确回答的问题数量计算每个学生的分数。
当超过40人同时或在同一天参加测验时,问题就开始了。我收到有关超过配额以及对数据存储区的读写次数的错误消息。
如果我理解正确,我的数据库太大会导致爆炸搜索:https://cloud.google.com/appengine/articles/
将数据库拆分为20个问题的20个数据库会解决问题吗?
我必须在星期三之前让它工作,我自己没有办法测试这个解决方案。
谢谢!
以下是我创建数据库的方法:
class ExpQuestionnaires(db.Model):
created = db.DateTimeProperty(auto_now_add = True)
username= db.StringProperty(required=False)
nmi1 = db.StringProperty(required=False)
nmi2 = db.StringProperty(required=False)
nmi3 = db.StringProperty(required=False)
nmi_happy = db.StringProperty(required=False)
nmi_pleasant = db.StringProperty(required=False)
nmi_good = db.StringProperty(required=False)
nmi_interested = db.StringProperty(required=False)
ai_content = db.TextProperty(required=False)
aic = db.TextProperty(required=False)
dm1 = db.StringProperty(required=False)
dm2 = db.StringProperty(required=False)
dm3 = db.StringProperty(required=False)
dm4 = db.StringProperty(required=False)
dm5 = db.StringProperty(required=False)
dm6 = db.StringProperty(required=False)
dm7 = db.StringProperty(required=False)
dm8 = db.StringProperty(required=False)
dm9 = db.StringProperty(required=False)
dm10 = db.StringProperty(required=False)
dm11 = db.StringProperty(required=False)
dm12 = db.StringProperty(required=False)
dm13 = db.StringProperty(required=False)
dm14 = db.StringProperty(required=False)
dm15 = db.StringProperty(required=False)
dm16 = db.StringProperty(required=False)
dm17 = db.StringProperty(required=False)
dm18 = db.StringProperty(required=False)
dm19 = db.StringProperty(required=False)
dm20 = db.StringProperty(required=False)
dm21 = db.StringProperty(required=False)
dm22 = db.StringProperty(required=False)
dm23 = db.StringProperty(required=False)
dm24 = db.StringProperty(required=False)
dm25 = db.StringProperty(required=False)
dm26 = db.StringProperty(required=False)
dm27 = db.StringProperty(required=False)
dm28 = db.StringProperty(required=False)
dm29 = db.StringProperty(required=False)
dm30 = db.StringProperty(required=False)
dm31 = db.StringProperty(required=False)
dm32 = db.StringProperty(required=False)
dm33 = db.StringProperty(required=False)
dm34 = db.StringProperty(required=False)
dm35 = db.StringProperty(required=False)
dm36 = db.StringProperty(required=False)
soep1 = db.StringProperty(required=False)
soep2 = db.StringProperty(required=False)
soep3 = db.StringProperty(required=False)
soep4 = db.StringProperty(required=False)
RteM1 = db.StringProperty(required=False)
RteM2 = db.StringProperty(required=False)
RteM3 = db.StringProperty(required=False)
RteM4 = db.StringProperty(required=False)
loc1 = db.StringProperty(required=False)
loc2 = db.StringProperty(required=False)
loc3 = db.StringProperty(required=False)
loc4 = db.StringProperty(required=False)
loc5 = db.StringProperty(required=False)
loc6 = db.StringProperty(required=False)
loc7 = db.StringProperty(required=False)
loc8 = db.StringProperty(required=False)
loc9 = db.StringProperty(required=False)
loc10 = db.StringProperty(required=False)
loc11 = db.StringProperty(required=False)
loc12 = db.StringProperty(required=False)
loc13 = db.StringProperty(required=False)
loc14 = db.StringProperty(required=False)
loc15 = db.StringProperty(required=False)
loc16 = db.StringProperty(required=False)
loc17 = db.StringProperty(required=False)
loc18 = db.StringProperty(required=False)
loc19 = db.StringProperty(required=False)
loc20 = db.StringProperty(required=False)
loc21 = db.StringProperty(required=False)
loc22 = db.StringProperty(required=False)
loc23 = db.StringProperty(required=False)
loc24 = db.StringProperty(required=False)
loc25 = db.StringProperty(required=False)
loc26 = db.StringProperty(required=False)
loc27 = db.StringProperty(required=False)
loc28 = db.StringProperty(required=False)
loc29 = db.StringProperty(required=False)
bis1 = db.StringProperty(required=False)
bis2 = db.StringProperty(required=False)
bis3 = db.StringProperty(required=False)
bis4 = db.StringProperty(required=False)
bis5 = db.StringProperty(required=False)
bis6 = db.StringProperty(required=False)
bis7 = db.StringProperty(required=False)
bas1 = db.StringProperty(required=False)
bas2 = db.StringProperty(required=False)
bas3 = db.StringProperty(required=False)
bas4 = db.StringProperty(required=False)
rei1 = db.StringProperty(required=False)
rei2 = db.StringProperty(required=False)
rei3 = db.StringProperty(required=False)
rei4 = db.StringProperty(required=False)
rei5 = db.StringProperty(required=False)
rei6 = db.StringProperty(required=False)
rei7 = db.StringProperty(required=False)
rei8 = db.StringProperty(required=False)
rei9 = db.StringProperty(required=False)
rei10 = db.StringProperty(required=False)
imp1 = db.StringProperty(required=False)
imp2 = db.StringProperty(required=False)
imp3 = db.StringProperty(required=False)
imp4 = db.StringProperty(required=False)
imp5 = db.StringProperty(required=False)
imp6 = db.StringProperty(required=False)
imp7 = db.StringProperty(required=False)
imp8 = db.StringProperty(required=False)
imp9 = db.StringProperty(required=False)
imp10 = db.StringProperty(required=False)
imp11 = db.StringProperty(required=False)
imp12 = db.StringProperty(required=False)
demo1 = db.StringProperty(required=False)
demo2 = db.StringProperty(required=False)
demo3 = db.StringProperty(required=False)
demo4 = db.StringProperty(required=False)
demo5 = db.StringProperty(required=False)
demo6 = db.StringProperty(required=False)
demo7 = db.StringProperty(required=False)
demo8 = db.StringProperty(required=False)
demo9 = db.StringProperty(required=False)
demo10 = db.StringProperty(required=False)
pQuizAttempts = db.IntegerProperty(required=False)
eQuizAttempts = db.IntegerProperty(required=False)
以下是我如何保存问题dm1,dm2,dm3,dm4,dm5,dm6的答案:
class RteDM1(Handler):
def get(self):
self.render("RteDM1.html")
def post(self):
dm1 = self.request.get("DM1")
dm2 = self.request.get("DM2")
dm3 = self.request.get("DM3")
dm4 = self.request.get("DM4")
dm5 = self.request.get("DM5")
dm6 = self.request.get("DM6")
username = self.request.cookies.get('username', 0)
dmdata = ExpQuestionnaires(username = username, dm1 = dm1, dm2 = dm2, dm3 = dm3, dm4 = dm4, dm5 = dm5, dm6 = dm6)
dmdata.put()
next = self.request.get("next")
if next == "yes":
self.redirect('/RteDM2')
我不依赖于将数据保存到cookie以使作弊更难(长篇故事),并且在我的应用程序或学生的计算机崩溃时至少得到部分答案。
以下是包含以下问题的网页:
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
body {width:900px; margin:20px auto 10px;background-color:#F0F8FF; font-size:16px; font-family:Arial;line-height:1.5em; text-align:justify;}
.screen { text-align:center; font-style: italic; }
.bold { text-align:center; font-weight: bold; }
.normal { text-align:center; font-weight: normal; line-height:30px}
a.next { text-align:center; padding:2px 5px; margin:0 47%; border:3px outset #ddd; background-color:#DDD;text-decoration: none;}
li {padding:5px 0}
input {margin:7px 10px 5px 15px}
input[type="submit"]{margin:15px 47%;}
.button {margin:15px 47%; width:100px}
.width1 {width:7% !important;text-align:center;padding:10px 2px;font-size:12px; }
.width2 {width:50% !important;text-align:left;padding:2px;}
td {margin:0 5px 0 0}
table {font-size:12px; border-collapse:collapse;width:100%;}
table, th, td {border: 1px solid black;padding:3px 10px;text-align:center;}
</style>
</head>
<body>
<p style="text-align:right;font-size:12px">3/17</p>
<p>Instructions</p>
<form method="post">
<p></p><br>
<table>
<tr>
<td class="width2"></td>
<td class="width1">1 <br/>very unlikely</td>
<td class="width1">2 <br/>unlikely</td>
<td class="width1">3 <br/>possibly unlikely</td>
<td class="width1">4 <br/>hard to tell</td>
<td class="width1">5 <br/>possibly likely</td>
<td class="width1">6 <br/>likely</td>
<td class="width1">7 <br/>very likely</td>
</tr>
<tr>
<td class="width2">Scenario 1</td>
<td><input type="radio" name="DM1" value="1"></td>
<td><input type="radio" name="DM1" value="2"></td>
<td><input type="radio" name="DM1" value="3"></td>
<td><input type="radio" name="DM1" value="4"></td>
<td><input type="radio" name="DM1" value="5"></td>
<td><input type="radio" name="DM1" value="6"></td>
<td><input type="radio" name="DM1" value="7"></td>
</tr>
<tr>
<td class="width2">Scenario 2</td>
<td><input type="radio" name="DM2" value="1"></td>
<td><input type="radio" name="DM2" value="2"></td>
<td><input type="radio" name="DM2" value="3"></td>
<td><input type="radio" name="DM2" value="4"></td>
<td><input type="radio" name="DM2" value="5"></td>
<td><input type="radio" name="DM2" value="6"></td>
<td><input type="radio" name="DM2" value="7"></td>
</tr>
<tr>
<td class="width2">Scenario 3</td>
<td><input type="radio" name="DM3" value="1"></td>
<td><input type="radio" name="DM3" value="2"></td>
<td><input type="radio" name="DM3" value="3"></td>
<td><input type="radio" name="DM3" value="4"></td>
<td><input type="radio" name="DM3" value="5"></td>
<td><input type="radio" name="DM3" value="6"></td>
<td><input type="radio" name="DM3" value="7"></td>
</tr>
<tr>
<td class="width2">Scenario 4</td>
<td><input type="radio" name="DM4" value="1"></td>
<td><input type="radio" name="DM4" value="2"></td>
<td><input type="radio" name="DM4" value="3"></td>
<td><input type="radio" name="DM4" value="4"></td>
<td><input type="radio" name="DM4" value="5"></td>
<td><input type="radio" name="DM4" value="6"></td>
<td><input type="radio" name="DM4" value="7"></td>
</tr>
<tr>
<td class="width2">Scenario 5</td>
<td><input type="radio" name="DM5" value="1"></td>
<td><input type="radio" name="DM5" value="2"></td>
<td><input type="radio" name="DM5" value="3"></td>
<td><input type="radio" name="DM5" value="4"></td>
<td><input type="radio" name="DM5" value="5"></td>
<td><input type="radio" name="DM5" value="6"></td>
<td><input type="radio" name="DM5" value="7"></td>
</tr>
<tr>
<td class="width2">Scenario 6</td
> <td><input type="radio" name="DM6" value="1"></td>
<td><input type="radio" name="DM6" value="2"></td>
<td><input type="radio" name="DM6" value="3"></td>
<td><input type="radio" name="DM6" value="4"></td>
<td><input type="radio" name="DM6" value="5"></td>
<td><input type="radio" name="DM6" value="6"></td>
<td><input type="radio" name="DM6" value="7"></td>
</tr>
</table>
<p class="button"><button type="submit" name="next" value="yes">Next</button></p>
答案 0 :(得分:0)
写入与保存的实体数量相关,读取与您检索的实体数量相关。
我们无法为您重新编写您的申请,但以下是一些节省费用的提示:
仅在查询中使用的索引属性。所有其他属性都应该是无索引的(索引= False)。此更改将极大地减少数据存储操作的数量和数据的大小。
无需将所有问题都作为属性放入单个实体中。现在,每当您想要保存对单个问题的响应时,您都会重写整个实体,从而产生所有相应的成本。每个问题应该是一个单独的实体 - 可能是问卷调查实体的子实体。然后,您可以以最低成本单独保存每个响应。此更改很可能会将应用的数据存储操作数量减少10-20倍。
答案 1 :(得分:0)
嗯 - 问题是,每次用户切换到下一页时,您是否需要保存答案? 您还可以将数据保留在服务器(会话对象)上,并仅在流程结束时保存到数据库。
还要确保将索引属性保持在较低水平:
新实体投放(每个实体,无论实体大小):每个索引属性值写入2次+写入+每个复合索引值写入1次
没有(直接)需要在问题或页面上编制索引。 当用户返回页面时,您只需检索所有问题,并让后端代码将页面的正确问题发送到前端。
我不是每个问题都写一个单独实体的粉丝 - 这会让你对你的回购做更多的阅读。 此外 - 这是一种非常规范化的方法 - 可能对您的应用无效。
更多地考虑您的架构:您的应用程序是如何使用的? 对我来说最简单的是什么?每个用户进行整个测验的1个实体?每页1个实体?每个问题1个实体。 如果你想限制读写=&gt;根据上面的作者计数选择您需要的设计。 并考虑您需要阅读实体的次数。 只需为每个设计写出1或2个场景并进行数学计算。