Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2005 是否有比ASP.NET 2.0匿名配置文件更有效的替代方案?_Sql Server 2005_Diskspace_Asp.net Profiles - Fatal编程技术网

Sql server 2005 是否有比ASP.NET 2.0匿名配置文件更有效的替代方案?

Sql server 2005 是否有比ASP.NET 2.0匿名配置文件更有效的替代方案?,sql-server-2005,diskspace,asp.net-profiles,Sql Server 2005,Diskspace,Asp.net Profiles,几年前我发现了ASP.NET配置文件,发现在我的网站上实现一些强大的功能既快捷又简单。我最终只使用了“匿名”配置文件属性,因为我没有使用ASP.NET成员资格,并且希望跟踪信息并为我网站的用户提供个性化设置,即使他们没有登录 快进3年,现在我正努力将我的aspnetdb数据库的大小保持在我的主机提供商的3GB限制之内。一年前,我决定只保留6个月的配置文件数据,现在每个月我都必须运行aspnet_profile_DeleteInactiveProfiles过程,然后向主机发出支持请求以截断数据库文

几年前我发现了ASP.NET配置文件,发现在我的网站上实现一些强大的功能既快捷又简单。我最终只使用了“匿名”配置文件属性,因为我没有使用ASP.NET成员资格,并且希望跟踪信息并为我网站的用户提供个性化设置,即使他们没有登录

快进3年,现在我正努力将我的aspnetdb数据库的大小保持在我的主机提供商的3GB限制之内。一年前,我决定只保留6个月的配置文件数据,现在每个月我都必须运行aspnet_profile_DeleteInactiveProfiles过程,然后向主机发出支持请求以截断数据库文件

真正的缺点是现在我已经实现了这个功能,网站依赖于这个数据库,每次我需要截断时都会有停机时间。今天真的吃了一块蛋糕——在对aspnetdb进行维护时,网站宕机了12个多小时,我最终创建了aspnetdb数据库的故障切换副本,这样我就可以让网站再次联机(在我写这篇文章时,原来的aspnetdb数据库仍然宕机)

去年,我重写了一些功能,因为它存储了一小部分二进制对象,我将其转换为存储一个逗号分隔的ID字符串,使其存储空间更小

我曾考虑过获得更多的磁盘空间,但现实情况是,仅仅为了保存每个用户最近查看的产品的列表,跟踪他们的“继续购物”按钮将其取回的类别,并存储总数量,而拥有一个每年增长4 GB的数据库是不值得的(仅限货币)这是在他们的购物车中。事实上,只有不到5%的数据被网站的重复访问者重复使用,但是没有办法提前告诉这些用户中的哪些人将返回访问他们的个人资料信息

因此,我的问题是,是否有一种更有效的方法来存储概要文件数据,这样它就不会占用太多空间,或者是否有其他方法来为支持此功能的每个用户创建概要文件数据库记录

我看了一下,但是有人能保证使用它是否会比默认的提供程序使用更少的磁盘空间来存储数据吗

更新:

我做了一些研究,似乎nvarchar(max)字段直接替换aspnetdb默认实现使用的ntext字段,但根据和,只需要一半的磁盘空间。这意味着我应该能够创建aspnetdb的新副本,修改整个架构和代码中的数据类型,并将数据传输到新数据库中。这应该修复数据存储方式以及执行收缩操作时发生的任何碎片

我现在已经完成了测试,并将此解决方案转移到了生产环境中。起初我认为会有问题,因为Microsoft将NText数据类型硬编码到SqlProfileProvider内部的存储过程调用中。但是,事实证明,SQL Server会隐式地将NText参数转换为nvarchar(MAX)简而言之,除了aspnet_Profiles表的PropertyNames和PropertyValuesString列上的类型之外,我不需要更改任何内容

数据必须重写到磁盘以释放空间,但我最终仅通过更改数据类型就节省了大约30%的总空间

另一个更新:

我还发现,尽管我每天都有大约700名独立访客,但平均每天的“用户”数量在aspnet_用户表中,平均值约为4000-5000。我推测这是由于一些用户在没有cookie的情况下浏览。我做了一些测试,发现如果配置文件未更新,则不会创建用户,但如果向配置文件写入用户(和配置文件)如果未启用Cookie,将在每次请求时创建

我正在为此制定一个解决方案。我正在尝试为webmethod的AJAX调用编写javascript。理论上,第二个请求(AJAX调用)如果启用cookie,则应存在.ASPXANONYMOUS cookie,因此我可以安全地写入配置文件。只有在会话开始时(由session.IsNewSession属性确定),才会将javascript注入页面。用户永远不应该知道AJAX调用-它只是告诉页面是否启用了Cookie,以便页面可以更新配置文件

当然,每个子序列请求都可以简单地检查cookies集合,以确保存在.ASPXANONYMOUS cookie。我很可能会创建一个共享函数,该函数可以由称为webmethod的AJAX和Page_Load事件直接调用,并使用IsNewSession属性来确定允许哪个请求运行cookieeck和后续配置文件更新


根据微软的说法,使用会话来跟踪cookies是否被启用,这是不符合目的的(因为会话依赖于cookies)他们建议将您的AreCookiesEnabled值持久保存到数据库中,但他们没有提到您应该如何跟踪保存该值的位置-如果未启用Cookie,您如何将请求链接到数据库记录?

我实现了我在原始帖子中提出的解决方法,但结果有点不确定与我最初描述的不同。修复实际上可以分为两部分-一部分用于修复禁用Cookie时更新数据库的问题,另一部分用于检测禁用Cookie时是否无需重定向

我已经把这封信寄出去了

因此,现在我将重点讨论第二部分——从请求的第一页将信息输入到配置文件中。这只需要进行修改
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not Me.IsPostBack Then

        If Session.IsNewSession Then
            Me.InjectProfileJavaScript()
        ElseIf AnonymousProfile.IsAnonymousCookieStored Then
            'If cookies are supported, and this isn't the first request, update the
            'profile using the current page data.
            UpdateProfile(Request.RawUrl, Request.UrlReferrer.OriginalString, CurrentProductID.ToString)
        End If

    End If

End Sub
Private Sub InjectProfileJavaScript()

    Dim sb As New StringBuilder

    sb.AppendLine("$(document).ready(function() {")
    sb.AppendLine("  if (areCookiesSupported() == true) {")
    sb.AppendLine("    $.ajax({")
    sb.AppendLine("      type: 'POST',")
    sb.AppendLine("      url: 'HttpHandlers/UpdateProfile.ashx',")
    sb.AppendLine("      contentType: 'application/json; charset=utf-8',")
    sb.AppendFormat("      data: ""{3}'RawUrl':'{0}', 'ReferralUrl':'{1}', 'ProductID':{2}{4}"",", Request.RawUrl, Request.UrlReferrer, CurrentProductID.ToString, "{", "}")
    sb.AppendLine()
    sb.AppendLine("      dataType: 'json'")
    sb.AppendLine("    });")
    sb.AppendLine("  }")
    sb.AppendLine("});")

    Page.ClientScript.RegisterClientScriptBlock(GetType(Page), "UpdateProfile", sb.ToString, True)

End Sub

Public Shared Sub UpdateProfile(ByVal RawUrl As String, ByVal ReferralUrl As String, ByVal ProductID As Integer)
    Dim context As HttpContext = HttpContext.Current
    Dim profile As ProfileCommon = CType(context.Profile, ProfileCommon)

    Dim CurrentUrl As New System.Uri("http://www.test.com" & RawUrl)
    Dim query As NameValueCollection = HttpUtility.ParseQueryString(CurrentUrl.Query)
    Dim source As String = query.Item("source")
    Dim search As String = query.Item("search")
    Dim OVKEY As String = query.Item("OVKEY")

    'Update the profile
    profile.TestValue1 = source
    profile.TestValue2 = search

End Sub
<httpModules>
    <add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</httpModules>
function areCookiesSupported() {
    var c='c';var ret = false;
    document.cookie = 'c=2;';
    if (document.cookie.indexOf(c,0) > -1) {
        ret = true;
    } else {
        ret = false;
    }
    deleteCookie(c);
    return ret
}
function deleteCookie(name) {
    var d = new Date();
    document.cookie = name + '=1;expires=' + d.toGMTString() + ';' + ';';
}
<%@ WebHandler Language="VB" Class="Handlers.UpdateProfile" %>

Imports System
Imports System.Web
Imports System.Web.SessionState
Imports Newtonsoft.Json
Imports System.Collections.Generic
Imports System.IO

Namespace Handlers

    Public Class UpdateProfile : Implements IHttpHandler : Implements IRequiresSessionState

        Public Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest

            If AnonymousProfile.IsAnonymousCookieStored Then

                If context.Session.IsNewSession Then
                    'Writing to session state will reset the IsNewSession flag on the
                    'next request. This will fix a problem if there is no Session_Start
                    'defined in global.asax and no other session variables are written.
                    context.Session("ActivateSession") = ""
                End If

                Dim reader As New StreamReader(context.Request.InputStream)
                Dim params As Dictionary(Of String, String) = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(reader.ReadToEnd())

                Dim RawUrl As String = params("RawUrl")
                Dim ReferralUrl As String = params("ReferralUrl")
                Dim ProductID As Integer = params("ProductID")

                PageBase.UpdateProfile(RawUrl, ReferralUrl, ProductID)
            End If
        End Sub

        Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
            Get
                Return False
            End Get
        End Property

    End Class

End Namespace
<!-- Required for anonymous profiles -->
<anonymousIdentification enabled="true"/>
<profile defaultProvider="SqlProvider" inherits="AnonymousProfile">
    <providers>
        <clear/>
        <add name="SqlProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="SqlServices" applicationName="MyApp" description="SqlProfileProvider for profile test web site"/>
    </providers>
    <properties>
        <add name="TestValue1" allowAnonymous="true"/>
        <add name="TestValue2" allowAnonymous="true"/>
    </properties>
</profile>