Database Amazon SimpleDB查询以查找;“朋友发帖”;
我一直在开发一个iPhone应用程序,它可以查询一个服务器,转发我在Amazon SimpleDB中存储的数据。我有一个由不同用户提交的数据库表。我正在与Facebook交互以检索Facebook好友,并希望查询“提交”以查找好友的帖子,如:Database Amazon SimpleDB查询以查找;“朋友发帖”;,database,amazon-simpledb,Database,Amazon Simpledb,我一直在开发一个iPhone应用程序,它可以查询一个服务器,转发我在Amazon SimpleDB中存储的数据。我有一个由不同用户提交的数据库表。我正在与Facebook交互以检索Facebook好友,并希望查询“提交”以查找好友的帖子,如: SELECT * FROM submissions WHERE userID = '00123' OR userID = '00124' OR .... (通过完整的朋友列表) 我认为这种select语句会导致Amazon查询受限- [每个Select
SELECT * FROM submissions WHERE userID = '00123' OR userID = '00124' OR ....
(通过完整的朋友列表)
我认为这种select语句会导致Amazon查询受限-
[每个Select表达式的最大比较次数:20]
你能想出一个方法,用SimpleDB优雅地完成这个任务吗?
我不想做一大堆20人的问题。
或者,我是否需要移动到其他数据库包,然后执行跨表查询
谢谢 您需要IN子句或临时表的联接。不幸的是,AmazonSimpleDB有其局限性。正因为这个原因,我们放弃了一个有前途的项目。在切换设备之前,我们使用了多线程和NextToken功能
您可以对SimpleDB执行并行(多线程)查询以获得提交,每个查询最多查找20个用户ID,然后将结果合并到一个列表中。不过,也许是时候考虑切换到MySQL或SQLServer了,可以上传一个IDS列表作为临时表,然后做一个简单的连接来获得结果。 < P>有一个用SimuldB做的方法,但是它不雅致,这更像是一种黑客行为,因为它要求您在提交项目中人工复制userid属性 这是基于这样一个事实,即虽然每个IN谓词只能有20个比较,但是如果每个IN谓词都命名不同的属性,则可以有20个IN谓词。因此,向表单的提交项目添加其他合成属性: userID='00123'userID_2='00123'userID_3='00123'userID_4='00123'。。。用户ID_20='00123' 对于给定的提交,它们都具有相同的值。然后,您可以通过一个查询获取最多400个好友的提交:
SELECT * FROM submissions
WHERE userID IN('00120','00121',...,'00139') OR
`userID_2` IN('00140','00141',...,'00159') OR
`userID_3` IN('00160','00161',...,'00179') OR
`userID_4` IN('00180','00181',...,'00199') OR
...
`userID_20` IN('00300','00301',...,'00319')
您可以在创建提交时填充19个额外属性(如果您有备用属性),并且提交的用户听起来不会改变。另外,您可能希望显式地命名要返回的属性(而不是使用*),因为现在在返回数据集中有19个您不关心的属性
从数据模型的角度来看,这显然是一种黑客行为。但话说回来,对于拥有400个或更少好友的用户,它提供了您想要的东西:一个查询,这样您就可以按日期或其他条件进行限制,按最近的排序,页面浏览结果等。不幸的是,400的容量无法容纳所有facebook用户的好友列表。因此,您可能仍然需要为大型好友列表实现一个多查询解决方案
我的建议是,如果SimuldB适合你的应用程序的需要,除了这个问题,然后考虑使用HACK。但是,如果您需要重复执行类似的操作,那么SimpleDB可能不是最佳选择。我创建了,并且碰巧有一些实用程序代码用于拆分和并行运行多个select查询,同时将每个select的in子句限制为20个值。我可能会在下一个Savant版本中发布这段代码,但这里是为那些认为它有用的人准备的:
/// <summary>
/// Invokes select queries that use parameter lists (with IN clauses) by splitting the parameter list
/// across multiple invocations that are invoked in parallel.
/// </summary>
/// <typeparam name="T">The item type</typeparam>
/// <typeparam name="P">The select parameter type</typeparam>
/// <param name="savant">The savant instance.</param>
/// <param name="command">The command.</param>
/// <param name="paramValues">The param values.</param>
/// <param name="paramName">Name of the param.</param>
/// <returns></returns>
public static List<T> SelectWithList<T,P>(ISimpleSavantU savant, SelectCommand<T> command, List<P> paramValues, string paramName)
{
var allValues = SelectAttributesWithList(savant, command, paramValues, paramName);
var typedValues = new List<T>();
foreach (var values in allValues)
{
typedValues.Add((T)PropertyValues.CreateItem(typeof (T), values));
}
return typedValues;
}
/// <summary>
/// Invokes select queries that use parameter lists (with IN clauses) by splitting the parameter list
/// across multiple invocations that are invoked in parallel.
/// </summary>
/// <typeparam name="P">The select parameter type</typeparam>
/// <param name="savant">The savant instance.</param>
/// <param name="command">The command.</param>
/// <param name="paramValues">The param values.</param>
/// <param name="paramName">Name of the param.</param>
/// <returns></returns>
public static List<PropertyValues> SelectAttributesWithList<P>(ISimpleSavantU savant, SelectCommand command, List<P> paramValues, string paramName)
{
Arg.CheckNull("savant", savant);
Arg.CheckNull("command", command);
Arg.CheckNull("paramValues", paramValues);
Arg.CheckNullOrEmpty("paramName", paramName);
var allValues = new List<PropertyValues>();
if (paramValues.Count == 0)
{
return allValues;
}
var results = new List<IAsyncResult>();
do
{
var currentParams = paramValues.Skip(results.Count * MaxValueTestsPerSimpleDbQuery).Take(MaxValueTestsPerSimpleDbQuery).ToList();
if (!currentParams.Any())
{
break;
}
var currentCommand = Clone(command);
currentCommand.Reset();
var parameter = currentCommand.GetParameter(paramName);
parameter.Values.Clear();
parameter.Values.AddRange(currentParams.Select(e => (object)e));
var result = savant.BeginSelectAttributes(currentCommand, null, null);
results.Add(result);
} while (true);
foreach (var result in results)
{
var values = ((ISimpleSavant2)savant).EndSelectAttributes(result);
allValues.AddRange(values);
}
return allValues;
}
private static SelectCommand Clone(SelectCommand command)
{
var newParameters = new List<CommandParameter>();
foreach (var parameter in command.Parameters)
{
var newParameter = new CommandParameter(parameter.Name, parameter.PropertyName, null);
newParameter.Values.Clear();
newParameters.Add(newParameter);
}
var newCommand = new SelectCommand(command.Mapping, command.CommandText, newParameters.ToArray())
{
MaxResultPages = command.MaxResultPages
};
return newCommand;
}
//
///通过拆分参数列表调用使用参数列表(带IN子句)的select查询
///跨并行调用的多个调用。
///
///项目类型
///选择参数类型
///学者的例子。
///命令。
///参数值。
///参数的名称。
///
公共静态列表SelectWithList(ISimpleSavantU savant,SelectCommand命令,列表paramValues,字符串paramName)
{
var allValues=SelectAttributesWithList(savant、command、paramValues、paramName);
var typedValues=新列表();
foreach(所有值中的var值)
{
添加((T)propertyvalue.CreateItem(typeof(T),values));
}
返回类型值;
}
///
///通过拆分参数列表调用使用参数列表(带IN子句)的select查询
///跨并行调用的多个调用。
///
///选择参数类型
///学者的例子。
///命令。
///参数值。
///参数的名称。
///
公共静态列表使用列表选择属性(ISimpleSavantU savant,SelectCommand命令,列表
参数值,字符串参数名)
{
参数CheckNull(“savant”,savant);
参数CheckNull(“命令”,命令);
参数CheckNull(“paramValues”,paramValues);
参数CheckNullOrEmpty(“paramName”,paramName);
var allValues=新列表();
如果(paramValues.Count==0)
{
返回所有值;
}
var results=新列表();
做
{
var currentParams=paramValues.Skip(results.Count*MaxValueTestsPerSimpleDbQuery).Take(MaxValueTestsPerSimpleDbQuery).ToList();
如果(!currentParams.Any())
{
打破
}
var currentCommand=Clone(命令);
currentCommand.Reset();
var参数=currentCommand.GetParameter(paramName);
parameter.Values.Clear();
parameter.Values.AddRange(currentParams.Select(e=>(object)e));
var result=savant.BeginSelectAttributes(currentCommand,null,null);
结果。添加(结果);
}虽然(正确);
foreach(结果中的var结果)
{
变量值=((ISimpleSavant2)savant).EndSelectAttributes(结果);
allValues.AddRange(值);
}
返回所有值;
}
专用静态选择命令克隆(选择