我正在制作一个倾听者,这样我就可以将多个游戏的游戏数据发布到我的服务器上。无论用什么设备,我都会用它来保持客户端的同步!这部分我完成了使用Entity和Linq进行插入并在它们被去同步时加载播放器数据。
服务器的每个网站大约需要2到10毫秒,具体取决于发送的数据。 (我希望没事!)。这主要是FirstOrDefault选择,修改一些数据和SaveChanges。
但服务器还必须使用记分板为客户端提供服务。 "今天/所有时间"和#34;仅限每个人/朋友"。
我尝试了一些Linq SQL查询。但是当我看到输出时,我真的很害怕它会如何预制(有成千上万的用户和数百万的得分记录)。
以下是一个例子:
using (BertEntities BGE = new BertEntities())
{
var query =
(from score in BGE.ScoreTable
join game in BGE.GameSession on score.GameSessionID equals game.ID
join user in BGE.User on game.UserID equals user.ID
where
game.PublicHighScore == true &&
game.Banned == false &&
game.GameID == GameID &&
score.LevelID == level
orderby score.Score descending
select new ScoreResult
{
ID = user.ID,
Name = user.FacebookName,
Score = score.Score,
Streak = score.Streak,
Time = score.Time
}).Skip(skip).Take(count);
return JsonConvert.SerializeObject(query.ToList());
}
会像这样执行
SELECT TOP (100)
[Project1].[Score] AS [Score],
[Project1].[ID] AS [ID],
[Project1].[FacebookName] AS [FacebookName],
[Project1].[Streak] AS [Streak],
[Project1].[Time] AS [Time]
FROM ( SELECT [Project1].[Score] AS [Score], [Project1].[Streak] AS [Streak], [Project1].[Time] AS [Time], [Project1].[ID] AS [ID], [Project1].[FacebookName] AS [FacebookName], row_number() OVER (ORDER BY [Project1].[Score] ASC) AS [row_number]
FROM ( SELECT
[Filter1].[Score] AS [Score],
[Filter1].[Streak] AS [Streak],
[Filter1].[Time] AS [Time],
[Extent3].[ID] AS [ID],
[Extent3].[FacebookName] AS [FacebookName]
FROM (SELECT [Extent1].[LevelID] AS [LevelID], [Extent1].[Score] AS [Score], [Extent1].[Streak] AS [Streak], [Extent1].[Time] AS [Time], [Extent2].[UserID] AS [UserID], [Extent2].[GameID] AS [GameID]
FROM [dbo].[ScoreTable] AS [Extent1]
INNER JOIN [dbo].[GameSession] AS [Extent2] ON [Extent1].[GameSessionID] = [Extent2].[ID]
WHERE (1 = [Extent2].[PublicHighScore]) AND (0 = [Extent2].[Banned]) ) AS [Filter1]
INNER JOIN [dbo].[User] AS [Extent3] ON [Filter1].[UserID] = [Extent3].[ID]
WHERE ([Filter1].[GameID] = @p__linq__0) AND ([Filter1].[LevelID] = @p__linq__1)
) AS [Project1]
) AS [Project1]
WHERE [Project1].[row_number] > 0
ORDER BY [Project1].[Score] DESC
我没有SQL专家,但对我来说这看起来很难。 (考虑到我希望这可以扩展,即使有数百万条记录和数千条请求而不会杀死服务器。)
这是数据库布局: www.invokergame.com/db.png
我想在ScoreTable表中存储我需要的所有数据,因此我避免进行连接。但这会导致大量重复数据,而且我很确定这是错误的方法。
也许我应该忘记Entity Linq,并将其写入ADO.NET SQL(我需要帮助)?
对于文字墙感到抱歉,我期待着一些明智的话语!
修改
好的TomTom,这是你伪造的吗?将我需要的所有数据拖到一个数据集中。然后使用LINQ更新或删除此列表中的项目,当用户创建新的高分时,或禁用PublicHighScore?
这将如何表现?
public class ScoreCacheItem
{
public Int64 ScoreTableID { get; set; }
public Guid GameID { get; set; }
public int LevelID { get; set; }
public Int64 UserID { get; set; }
public string Name { get; set; }
public int Score { get; set; }
public int Streak { get; set; }
public double Time { get; set; }
public DateTime Today { get; set; }
public int Today_Score { get; set; }
public int Today_Streak { get; set; }
public double Today_Time { get; set; }
}
public sealed class ScoreCacheSystem
{
private List<ScoreCacheItem> FScoreCache = new List<ScoreCacheItem>();
private object FLock = new object();
private List<ScoreCacheItem> LoadAllScores()
{
using (BertEntities BGE = new BertEntities())
{
var query =
(from score in BGE.ScoreTable
join game in BGE.GameSession on score.GameSessionID equals game.ID
join user in BGE.User on game.UserID equals user.ID
where
game.PublicHighScore == true &&
game.Banned == false
orderby score.Score descending
select new ScoreCacheItem
{
ScoreTableID = score.ID,
GameID = game.GameID,
LevelID = score.LevelID,
UserID = user.ID,
Name = user.FacebookName,
Score = score.Score,
Streak = score.Streak,
Time = score.Time,
Today = score.Today,
Today_Score = score.Today_Score,
Today_Streak = score.Today_Streak,
Today_Time = score.Today_Time
});
return query.ToList();
}
}
public List<ScoreCacheItem> HighScores {
get
{
lock (FLock)
{
if (FScoreCache == null)
{
FScoreCache = LoadAllScores();
}
return FScoreCache;
}
}
}
}
答案 0 :(得分:0)
您在SQL方面遇到了严重问题。 EF做了相当不错的SQL - 但在这里我认为一般使用SQL Server是不好的。
如果您需要以超快的速度回答这种类型的查询,那么请从内存中执行此操作 - 而不是从数据库服务器执行。内存中查找对于对数据分发重复且时间敏感的简单查询是典型的(金融交易 - 没有人会将价格写入数据库然后让客户端拉出它们;在将它们写入商店时分发它们)。 p>
否则你就可以伪造它 - 我想到了缓存。使用此体系结构优化对重要数据库服务器的要求,您无法做很多事情。确保您的指数到位。从查询计划开始工作,确保您不会遗漏任何内容。
但实际上,尽量避免点击SQL Server - 所有级别的缓存输出。而且,SQL非常简单,BTW。当您点击2-3个屏幕长分析查询时,事情变得有趣;)数百万条记录不是问题,主要问题是并发请求。连接最好具有读取提交的隔离,以确保您不设置锁定。然后获得一个合适的服务器并扩展,除非你改变架构。
我想在ScoreTable表中存储我需要的所有数据,所以 我避免加入。但这会导致很多重复 数据,我很确定这是错误的方法。
绝对不是 - 不是错误的做法。非规范化在读取繁重的报告数据库中是典型的。您可以使用触发器自动维护此表。在您的情况下是否有意义必须使用良好的数据集进行测试。数据仓库中的标准做法通常不是很糟糕,尽管这些通常涉及实际数据量(数十亿行,而不是像一百万或两行一样微不足道)。在我上一次大型数据仓库项目中,我们每天要加载大约4.5亿行 - 并且必须将它们归档10年才能进行报告。查找&#34; Star Schema&#34;在谷歌上。基本只读/数据仓库方案的规则是不同的。