Sunday, March 20, 2011

Is it excessive to own server hardware?

Since there is a large pool of passionate developers in this community, I would like to gather your opinions on this matter - do you think it is excessive, or advantageous, to purchase and operate actual server hardware at home to spice your own development and learning efforts?

Back in 2003/4 when I jumped into the development line, I felt servers only belonged to the data centre, and did not believe in the pricing of servers for home use; consumer computing power was already pretty solid (back then), and similarly-speced PCs could be had for a fraction of the cost. Having assembled my own PCs since i was a school kid, I viewed the activity of obtaining second-hand components to build a new PC as an easy task. It was straightforward to prepare a PC that would act as a dedicated Windows 2003 server for my development tests. But for over three years now, I have been operating on real servers, albeit low-end models. I ended up in this state due to a number of factors.

  1. Stability. Server hardware built to work properly together. Tested to run server operating systems. Hardware that I assemble together may or may not work due to all those funny instances of unexpected incompatibilities. And unfortunately I ran into those situations more often than I should, like having to figure out why the PC won't boot up because I have the RAM modules plugged in a particular order, or by simple use of a particular DVD drive. I have not seen a single BSOD for my servers.
  2. Durability. I leave my servers running 24x7 and for years have (thankfully) not experienced any failure in server hardware. In contrast my PCs are just cursed with rapid failure rates. Even my vendor-purchased laptops eventually sport funny problems one way or another (especially with power supply units).
  3. Warranty. I may have warranty for individual PC parts, but the warranty for the computer as a whole is against myself. If something were to fail, I myself was the person to call up for help. And call myself I did several times. With the server however, I call techsupport and get them to replace parts.
  4. Capacity. Virtualization is truly a wonderful thing. Makes setting up single-purpose machines so much easier to manage. I directly loaded my first server to the max with 4GB RAM and happily ran a variety of virtual machines, simulating the multi-server/workstation environments I needed. Now my new server has capacity for 24GB RAM to afford the bigger scenarios I am looking to experiment with (e.g. AD domains, BizTalk server group, TFS group, etc).

All in all, with cranky DIYs I spent more time troubleshooting hardware problems than working on actual development issues. When I threw in the money to purchase real servers there was an instant drop in hardware problems in my life. I would probably have bought a vendor-built workstation too if only I could find a configuration that suited my development needs.

Now, some of my tech friends who are passionate with their work also operate their own servers at home. The thing is, most other folks/colleagues get rather surprised that I would actually spend cash for this category of machines. Some would classify me as insane. Have I truly gone overboard?

UPDATE - Clarification on server usage

The base server (Windows Server 2008) serves basic IIS 7/ASP.NET, SQL Server 2008, and Subversion services. But the largest role it plays is hosting a variety of virtual machines in Hyper-V. I am not a developer who is merely told to whack out application code against a single database and check it into some version control repository then go home without worrying how the application and implementation works out in a production environment. As a solutions integrator, I have to get an understanding of the client/customer environment and think of the big-picture solution that includes infrastructure and deployment concerns. Software application development, while being my primary role, is but a part of the solution.

I frequently find myself having to experiment and discover if certain suggestions or approaches would work for a given environment, and have had to prepare virtual servers like a forest of domains (controllers), web servers, database servers, BizTalk server groups, Team Foundation server, etc to conduct my analysis and solidify my recommendations. These virtual machines work as my personal POCs. The scenarios I face continue to grow larger, and I definitely do not see how I can get to learn how to handle these situations without a base platform that allows me to virtualise and simulate them.

From stackoverflow
  • I think that if you are a programmer you should focus on programming. Having an actual live web server it's not easy or cheap.

    Just think about it, you must have a good network connection with a good upload rate, a good machine dedicated just to werform as a server. Not even going to talk about the electrical costs or the refrigerating system, because you will need to place the server on a room that you do not use(cause is just simply annoying to hear those vents working when you are trying to rest).

    There are hundreds of companies that provide this service for almost nothing, when i had that decision to make, i just choose one of them and never thought twice.

    Don't get me wrong, i did had a web server at home, just to learn how to set one up, it was fun and rewarding but i could never provide a professional server just because it need 24/7 attention to prevent downtimes.

    icelava : I do not run just a web server, unfortunately. I operate forest domain controllers, BizTalk Servers, SQL Servers, Team Foundation Server, ISA server, different forms of client Windows XP for different scenarios, etc.
    annakata : I agree, every time I get involved with hardware it's just an upsetting and/or frustrating and/or tiresome experience. Especially printers. I hate printers.
    Cruachan : Hmm, personally I think as a reasonably well rounded developer you should have *some* familiarity with hardware, network configuration and the like. Just at the level where if presented with a problem you can make a reasonable stab at fixing it - or knowing you need professional sysop help.
    Sergio : And that is exactly what i said in the last paragraph. It is nice to know but i think it is just to much work/expenses to be worthwhile to maintain a working server.
    icelava : Btw, I do have an empty room to house my extraneous computers :-) yes electricity can be expensive but i feel ignorance on infrastructure issues is costly when I possess no knowledge and opinion to advise the client.
    icelava : Oh i probably should have answered your first point. As per my clarification, I am not just a programmer. I look at complete solutions to deliver to the client, including server/network infrastructure.
  • I think having some familiarity with server hardware makes you a more rounded technologist, so go for it. There are elements to a "proper" server you generally don't build into a home built system, like hot swappable drives and PSUs, remote access cards (like a Dell DRAC) etc.

    Even if server admin isn't your main job function, as your career progresses you may increasingly become involved in buying hardware and assessing quotes from vendors. The extra knowledge can certainly come in useful there.

    icelava : Main job is developer, but I handle lots of architecture, infrastructure, deployment matters.
  • I think whatever will have a ROI (return of investment) higher than 1.1 is ok to do it. In your specific situation i think in the short term you will defiantly loose money, but in the long run you may gain thought other added value. You could go for a somewhat cheaper than the average hardware to balance the costs.

    icelava : In fact, a high-end workstation costs more than my server. I bought low-end departmental class servers, which is a good compromise.
  • I used to operate my own web server, built on Compaq server-class hardware. However, these days, I don't want to be responsible for such a beast of a machine. The power draw from that server was immense, as was the noise and heat it generated. Ignoring the financial issues of providing power and cooling, the simple fact is that (to me) it is not worth the effort. There is nothing that I need to do that requires server-class hardware. In fact, there is nothing I need to do at home that can't be achieved on a virtual machine on my MacBook.

    YMMV, of course.

    icelava : Have you tried to simultaneously run domain controllers, BizTalk app server, BizTalk database server, web server, Team foundation server, Sharepoint server in your MacBook?
    ZombieSheep : No, but as I said, YMMV. For the record, I have run an AD controller, BT server and a separate dev machine (with SQL) and it wasn't too bad.
    ZombieSheep : The other point is that the original question was a subjective one. I have no real need to run BT or MOSS at home so I don't.
  • It really depends on your particular needs.

    Having your own development and learning servers may be considered excessive in general.

    In fact, for typical development, I believe you can even put a virtual server on your development desktop workstation under VirtualBox or whatever you prefer. No need to have separate physical PCs or servers.

    If you do need them though, then whatever gets the work done would suffice, right? Of course, "server"-servers are usually better suited for the job. If you can afford the price difference and it makes sense for you, why not?

    icelava : In fact, my workstation has its own Virtual Server 2005 installation to run its own group of virtual machines. But those machines are different from the ones I run on the server.
  • I agree with Gnudiff, why would you need server hardware with rock-solid 24x7 availability for playing around with at home? Yes there are some technicalities it may be useful to learn, but it may be easier to get hold of an old box at work and fiddle with that. Then it can be kept somewhere out of the way and won't cost you anything.

    Between this site, Google Reader and Facebook, I don't have enough time for my wife, let alone managing my own servers at home!

    icelava : The largest factor, as updated above, is the capacity of a server. 8GB RAM is not enough for my environmental scenarios.
  • My workstation is a Core 2 Quad with 8GB RAM and RAID 0 and RAID 1 hard disks running Vista x64. It works pretty well for all my needs. I don't think I need a separate server. Invest on your workstation and forget about spending lots of time configuring stuff!

    icelava : I spend lots of time troubleshooting my workstation hardware. I hardly spend time worrying about my server hardware.
  • I think there's a whole spectrum of options between the two extremes of:

    • build your own PCs from scratch (lots of effort - you might be the first to run an OS on that particular combination of components)
    • buy server grade hardware from a major manufacturer

    For the needs you describe, something like a a high end Lenovo desktop is likely to provide the reliability and resilience you need, far cheaper than server grade hardware.

    Ironically of course, the really big services companies (Google, Amazon etc.) are spending less on individual servers, buying more of them, and writing software that routes around failed nodes.

    icelava : I did start out with the former option, and ended up with the latter. So yes, I gone through the spectrum. Except, I cannot afford high-end quadruple redundancy systems; I bought low-end servers for a good compromise.
  • If you're looking only to learn, and that too as a programmer and not a network or server engineer I do agree that spending on a professional server setup is overkill. You'll be done with the novelty in the first few weeks and then it will just sit there on your lap like a beached whale.

    Do you have any specific needs that cannot be served by a regular computer with server software installed?

    icelava : I come up with complete solutions, not just a software program.
    icelava : By "complete solutions" it means system architecture, network infrastructure, deployment/distribution.
    icelava : Sorry I did not address your last question - please read updated description above.
  • Running data-centre level hardware would be over the top - you don't need hot swappable drives and the like and they'd be a waste of money, but certainly if you're serious about your own development work then running a low end SME level server is a good move for the security and convenience it gives you.

    Myself I run my own Consultancy/Development (the accepted answer) business, and I run a small network to support that. I run a HP SME server with 250GB RAID, 4Gb RAM, Windows 2003. It's on 24/7 and does everything you'd expect a server to be doing in any small business. The main network connects to the Internet by a good quality SME level ADSL account.

    In addition I run a Linux server on similar hardware that is connected to the Internet by another ADSL account (just a basic cheap business account) on a separate phone line. This gives me backup in the case of ADSL issues (does happen occasionally that one goes down and the other stays up) but also means I can run a low level internet server for showing things to clients on a dedicated and isolated line - obviously not production quality but good enough for testing (I have a couple of dedicated servers co-hosted elsewhere running client sites, but they can't be extensively used for non-production purposes obviously and having the hardware in-house means I can adjust the configuration more easily)

    It's really a question of tuning what your requirements are to the hardware to support that - just like deploying any hardware into a client actually. As a developer you'll want security and convenience just the same as any small business, but equally you need good ROI - no point in spending $1000 on additional server gold-plating when that would buy you a 30" monitor for example. Just pretend you have a critical but understanding business partner (of the Joel level of coder-focus) who you have to justify your expenditure too and be honest with yourself over what you need - with a sprinkling of indulgence.

    EDIT in response to reading some other comments about not needing server hardware for your own personal development use: Point you have to ask is what happens when your alternative suffers a hardware failure? I suggest that having a separate server makes it more likely you can recover from a catastrophic failure more quickly: that's likely to happen less often anyway, your more likely to have backups, and the restore is likely to be simpler.

    Even if you're just messing around with personal development loosing work and having to restore complex configurations both takes time and is a demoralising pain to do. You should value your own time at a reasonable $/h rate even when its just fun stuff and factor in that against the cost of a basic server and associated backup regime - with hardware prices at the level they are it's really a no-brainer.

    Cyril Gupta : I thought he was a programmer. How do you expect him to service a hardware failure? Suppose my hard disk blew... Are programmers in charge of changing hard disk in professional server environments?
    bruceatk : Where I work I do a little of everything. I'm sure a lot of developers have to keep hardware going.
    Cruachan : He's not in a professional server environment in this case, just asking if he should use server level hardware to support home use and balancing the additional costs vs lower failure rates. Of course in an office you get IT support to fix a failing drive...
    Cruachan : ... but if it's your own hardware you're responsible for it and of course you should be capable of swapping a failing harddrive. Basic familiarity with hardware is necessary as a coder - sometimes simply because failing hardware can cause software issues.
    icelava : The servers i bought are departmental-level tower models, not rack-mountable data centre models. I use Acronis True Image Workstation/Enterprise Server to easily backup and restore disk images.
    icelava : @Cyril: that is why I choose to buy server hardware - i get technical support from the vendor in the event of hardware failure. And server hardware fails slower than consumer hardware.
  • Unless you need to be experienced in that hardware I think it's overkill. I have run at least one server at home for the last 13 years. I build/upgrade my own PC's. I have supported my family (5 workstations and 5 laptops) for longer than that. The servers that I use are built from parts left over from upgrades. I currently have a 3 server configuration. I have my main server (AMD 3800 X2 w/4 gig) that I use for the family's file server and an IIS web server. It also is running Ubuntu in a VM. This box handles all of our backups. I have a 2nd box (AMD 2600 w/4 gig) that is used for Windows Media Center, and as a backup for my main server, it replicates the contents of my main server to it's local storage. My 3rd box (AMD 3200 w/4 gig) is my play box and is currently running Windows Server 2008.

    In 13 years (running 24x7) I have had two hardware failures that I relate to power (they occurred after a power outage), a network card and a motherboard. I have had one hard disk failure (it just started getting a lot of errors/retries, I didn't lose any data). After the motherboard failure I bought an inexpensive UPS. I then added a 2nd one when I added the 3rd server.

    My used left over hardware has been extremely reliable. The only issues that I have had with hardware compatibility is with Ubuntu on a Compaq. After that one episode I started only using generic hardware. I would recommend everyone have at least one server to centrally locate things that need to be backed up.

    All of my servers have gone on to relatives to use as a 2nd or 3rd PC as they have been retired. I ran one server for about 5 years, two servers for about 6 years and I have been running three for the last 2 years. My oldest server box the AMD 2600 served it's life for 3 years as my wife's PC and has been a server for 2 years.

    Update

    I never really thought about it before, but it dawned on me that the reason that I have had such reliable hardware is because the hardware I use has already had a couple years of testing. With the exception of a few hard drives all of my hardware has proven to be reliable before it makes it to being used as a server.

    icelava : You are pretty lucky. My luck ain't so good with PC parts, which caused me plenty pain when I first setup a dedicated PC to act as a server. Non-stop hardware problems.
    bruceatk : Somebody has to offset my good luck. :) I believe using a UPS makes all the difference. I pretty much buy everything from TigerDirect or NewEgg and I don't buy best or the cheapest. I try to find the sweet spot.
    icelava : Nah my hardware problems were not power surge situations.

Is there a standardised way to embed metadata (e.g. version, license) in SWC components?

Scenario: there is an Adobe Flex 3 project which uses several third-party libraries and components in the form of SWC files.

How can we know "what is inside" those SWC files? Specifically, how can I make sure that the project uses the latest versions of all those components?

According to official Adobe Flex 3 help, "you can define" (sic) a version property for a component that you intend to package and distribute. Something along the lines of:

private static const version:String = '1.0.0.42';

But that property is not treated in any special way by Adobe's authoring tools, and I suspect that it is not commonly used by the community, anyway.

The file catalog.xml that is inside all SWC components doesn't seem to contain anything useful in that sense.

Are developers distributing SWC usually embedding metadata in those files in any way? Is there a standardised way to retrieve data such as version, license, author and copyright from a SWC file?

From stackoverflow
  • You are making an interesting point.

    Adobe has provided a way to include basic metadatas in SWFs (and thus in SWCs) but this is stored in the binary and there's no way to extract it without decompilation.

    Interestingly, if one knows how to read a SWF, extracting metadatas is fairly easy. But most of the time it doesn't contain any useful information because obviously authoring tools don't let you simply view it...

    So I guess first we need some integration in our authoring tools, then we may begin finding useful information in the metadatas :)

    tripu : Thank you, Philippe. Where is the documentation about that metadata that can be included in `SWF`'s?
  • SWCs are generally distributed in a package with other supporting files, such as documentation and examples. Version, license, and author information is usually available as part of that package in a separate readme or license file. I've never seen component developers in the Flex world compile that sort of information into the SWC itself.

  • I would consider it good practice to include the version name in the .swc file itself. For example, if you use the Mate framework, the swc filename is something like Mate_08_5.swc. At a quick glance, you can see that you're using version 0.8.5.

    As far as license goes, usually you distribute a LICENSE text file within the .zip that contains your .swc file.

  • You could look into RSL digests. These attach a different hash value to each version of a particular library (swc/library/libraries/digests in the catalog.xml file) . Then all you have to do is only load the library with the known digest value.

    If you don't have any control over the SWC files being used and they're not using digests, you are kind of stuck with whatever proprietary versioning system the vendor is using though.

How to Optimize/Speedup Code Execution C#, Windows.Net

I have following Code Block Which I tried to optimize in the Optimized section

DataSet dsLastWeighing = null;
DataSet ds = null;
DataSet dsWeight = null;
string strQuery = string.Empty;
string strWhere = string.Empty;
Database db = null;

#region Original Code Block
      try
      { 
       db = DatabaseFactory.CreateDatabase();

       strWhere = "WHERE SESSION_ID = '"+pSessionID+"'"; 
       strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("DeleteWeightRecent",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");
       db.ExecuteNonQuery(System.Data.CommandType.Text, strQuery);

       strWhere = "WHERE LAB_ID = 0";
       strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("InsertWeightRecent",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");
       db.ExecuteNonQuery(System.Data.CommandType.Text, strQuery);

       strWhere = strWhere = "WHERE SESSION_ID = '"+pSessionID+"'"; 
       strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("GetPatientID",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");
       ds = (DataSet) db.ExecuteDataSet(System.Data.CommandType.Text, strQuery);

       foreach(DataRow dr in ds.Tables[0].Rows)
       {
        if (db.ToString() == "Microsoft.Practices.EnterpriseLibrary.Data.SqlBase.SqlBaseDatabase")
        {
         strWhere = "WHERE LAB_ID=0 AND PAT_ID ="+ int.Parse(dr["PAT_ID"].ToString())+" AND WHEN IN(SELECT MAX(WHEN) FROM PATIENT_LAB WHERE LAB_ID=0 AND PAT_ID="+ int.Parse(dr["PAT_ID"].ToString())+")"; 
        }
        else if (db.ToString() == "Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase")
        {
         strWhere = "WHERE LAB_ID=0 AND PAT_ID ="+ int.Parse(dr["PAT_ID"].ToString())+" AND [WHEN] IN(SELECT MAX([WHEN]) FROM PATIENT_LAB WHERE LAB_ID=0 AND PAT_ID="+ int.Parse(dr["PAT_ID"].ToString())+")"; 
        }
        strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("GetWeight",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");

        strMain.append(strQuery+" ");
        dsWeight = (DataSet) db.ExecuteDataSet(System.Data.CommandType.Text, strQuery);


        foreach(DataRow drWeight in dsWeight.Tables[0].Rows)
        {       
         strWhere =  "WHERE PAT_ID = "+int.Parse(dr["PAT_ID"].ToString())+" AND SESSION_ID ='"+pSessionID+"'";
         strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("UpdateWeightRecent",db.ToString(),pFacilityID,pSessionID,strWhere,decimal.Parse(drWeight["LEVEL"].ToString()),DateTime.Parse(drWeight["WHEN"].ToString()).ToUniversalTime(),int.Parse(drWeight["IS_BAD"].ToString()),drWeight["NOTE"].ToString());
         db.ExecuteNonQuery(System.Data.CommandType.Text, strQuery); 
        }

       }

       strWhere = " ORDER BY W.IS_BAD DESC, P.LASTNAME ASC, P.FIRSTNAME ASC,P.MIDDLENAME ASC";
       strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("GetPatientLastWeight",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");
       dsLastWeighing = (DataSet) db.ExecuteDataSet(System.Data.CommandType.Text, strQuery);     
      }
      catch(Exception ex)
      {
       throw ex;
      }
      finally
      {
       db = null;
       ds= null;
       dsWeight= null;
      }
      return dsLastWeighing;
      #endregion




--Optimized Section--

    #region Optimized Code Block

      try
      { 
       StringBuilder strMain=new StringBuilder();
       db = DatabaseFactory.CreateDatabase();

       //StartTime=DateTime.Now.ToLongTimeString();
       strWhere = "WHERE SESSION_ID = '"+pSessionID+"'"; 
       strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("DeleteWeightRecent",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");
       //EndTime=DateTime.Now.ToLongTimeString();
       //db.ExecuteNonQuery(System.Data.CommandType.Text, strQuery);
       strMain.append(strQuery+" ");

       strWhere = "WHERE LAB_ID = 0";

       //StartTime=DateTime.Now.ToLongTimeString();
         strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("InsertWeightRecent",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");
       //EndTime=DateTime.Now.ToLongTimeString();

       //db.ExecuteNonQuery(System.Data.CommandType.Text, strQuery);
       strMain.append(strQuery+" ");

       strWhere = strWhere = "WHERE SESSION_ID = '"+pSessionID+"'"; 
       //StartTime=DateTime.Now.ToLongTimeString();
         strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("GetPatientID",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");
       //EndTime=DateTime.Now.ToLongTimeString();
       //ds = (DataSet) db.ExecuteDataSet(System.Data.CommandType.Text, strQuery);

       strMain.append(strQuery+" ");
       //StartTime=DateTime.Now.ToLongTimeString();
        ds = (DataSet) db.ExecuteDataSet(System.Data.CommandType.Text, strMain.ToString());
       //EndTime=DateTime.Now.ToLongTimeString();

       strMain=null;


       foreach(DataRow dr in ds.Tables[0].Rows)
       {
        //StartTime=DateTime.Now.ToLongTimeString();
        if (db.ToString() == "Microsoft.Practices.EnterpriseLibrary.Data.SqlBase.SqlBaseDatabase")
        {
         strWhere = "WHERE LAB_ID=0 AND PAT_ID ="+ int.Parse(dr["PAT_ID"].ToString())+" AND WHEN IN(SELECT MAX(WHEN) FROM PATIENT_LAB WHERE LAB_ID=0 AND PAT_ID="+ int.Parse(dr["PAT_ID"].ToString())+")"; 
        }
        else if (db.ToString() == "Microsoft.Practices.EnterpriseLibrary.Data.Sql.SqlDatabase")
        {
         strWhere = "WHERE LAB_ID=0 AND PAT_ID ="+ int.Parse(dr["PAT_ID"].ToString())+" AND [WHEN] IN(SELECT MAX([WHEN]) FROM PATIENT_LAB WHERE LAB_ID=0 AND PAT_ID="+ int.Parse(dr["PAT_ID"].ToString())+")"; 
        }
        strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("GetWeight",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");

        strMain.append(strQuery+" ");
        //EndTime=DateTime.Now.ToLongTimeString();
        //dsWeight = (DataSet) db.ExecuteDataSet(System.Data.CommandType.Text, strQuery);

        /*
        foreach(DataRow drWeight in dsWeight.Tables[0].Rows)
        {       
         strWhere =  "WHERE PAT_ID = "+int.Parse(dr["PAT_ID"].ToString())+" AND SESSION_ID ='"+pSessionID+"'";
         strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("UpdateWeightRecent",db.ToString(),pFacilityID,pSessionID,strWhere,decimal.Parse(drWeight["LEVEL"].ToString()),DateTime.Parse(drWeight["WHEN"].ToString()).ToUniversalTime(),int.Parse(drWeight["IS_BAD"].ToString()),drWeight["NOTE"].ToString());
         db.ExecuteNonQuery(System.Data.CommandType.Text, strQuery); 
        }
        */
       }


       dsWeight = (DataSet) db.ExecuteDataSet(System.Data.CommandType.Text, strMain.ToString());
       strMain=null;
       //StartTime=DateTime.Now.ToLongTimeString();
       for(int i=0;i<dsWeight.Tables.Count;i++)
       {
        foreach(DataRow drWeight in dsWeight.Tables[i].Rows)
        {       
         strWhere =  "WHERE PAT_ID = "+int.Parse(dr["PAT_ID"].ToString())+" AND SESSION_ID ='"+pSessionID+"'";
         strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("UpdateWeightRecent",db.ToString(),pFacilityID,pSessionID,strWhere,decimal.Parse(drWeight["LEVEL"].ToString()),DateTime.Parse(drWeight["WHEN"].ToString()).ToUniversalTime(),int.Parse(drWeight["IS_BAD"].ToString()),drWeight["NOTE"].ToString());
         strMain.append(strQuery+" ");
         //db.ExecuteNonQuery(System.Data.CommandType.Text, strQuery); 
        }
       }
       db.ExecuteNonQuery(System.Data.CommandType.Text, strMain.ToString()); 
       //EndTime=DateTime.Now.ToLongTimeString();

       //StartTime=DateTime.Now.ToLongTimeString();
       strWhere = " ORDER BY W.IS_BAD DESC, P.LASTNAME ASC, P.FIRSTNAME ASC,P.MIDDLENAME ASC";
       strQuery = SQ.BusinessLogic.SQLQueryFactory.GetPatientLastWeighing("GetPatientLastWeight",db.ToString(),pFacilityID,pSessionID,strWhere,0,DateTime.Now.ToUniversalTime(),0,"");
       dsLastWeighing = (DataSet) db.ExecuteDataSet(System.Data.CommandType.Text, strQuery); 
       //EndTime=DateTime.Now.ToLongTimeString();
      }
      catch(Exception ex)
      {
       throw ex;
      }
      finally
      {
       db = null;
       ds= null;
       dsWeight= null;
      }
      return dsLastWeighing;


      #endregion

Can This Further be optimized .. Just concentrate on minimizing the loops.. I am not getting any ideas further..Any Help would be appreciated

From stackoverflow
  • If C#’s StringBuilder is anything like Java’s StringBuilder then a line like

    strMain.append(strQuery+" ");
    

    is a sure sign that you have not understood what StringBuilder is for.

    In Java that line would be compiled to

    strMain.append(new StringBuilder().append(strQuery).append(" ").toString());
    

    I’m pretty sure that that can not be called “optimized”.

    Jon Limjap : Yes Bombe, .NET StringBuilders work the same way as Java StringBuilders ;)
    Bombe : Ah, thanks for the information. :)
    Joel Mueller : No, actually that's not true. String concatenation is not compiled into StringBuilder calls in C#. The StringBuilder object itself is likely very similar to the Java version, but string concatenation does not use it implicitly.
  • I would suggest:

    • Use parameterised SQL
    • Get rid of the catch block, or at least use "throw" instead of "throw ex" so you don't lose the information
    • Get rid of the finally block - it's not helping you
    • Declare variables when they're first needed, not all at the top of the method
    • Break the method up into more manageable sections

    When all those have been done, you'll be in a better place to tune the performance. At that point, profile the app and see whether the pain point is actually in the .NET code or in the interaction with the database. In my experience, database applications are usually improved by:

    • Improving the SQL queries
    • Reducing the round-trips
    • Optimising the database (applying indexes etc)
    Mehrdad Afshari : +1. Correctness and simplicity are more important than pure performance.
    Bombe : +1. What Mehrdad said.
  • I don't know about the loops, but here are a few pointers

    • Don't use the strQuery+" " system in your stringbuilders. Append the " " too.
    • If you're looking for optimized SQL performance what're you doing with a dataset. Use a Datareader instead.
    • Listen to Jon Skeet.

    I think your code needs a re-work as to how it's modeled to get a good performance boost. Personally I avoid datasets when I can.

  • Minor issues: strWhere is a string, and you're doing a lot of manipulations. You'll probably be better off using StringBuilder for this. You may also see a small benefit from initializing your StringBuilder with a suitable length.

    Jon Skeet : I strongly suspect that the in-memory string manipulation will pale into insignificance as soon as the first database query is involved though.
  • Maybe you have optimized the creation of the SQL string, but I think this is peanuts compared to the time that it takes to communicate with the SQL server.

    You win a few milliseconds by optimizing your strings, but loose a lot by using a Dataset.

    I think you should focus on that part first. And not just the dataset thing, there is a lot more to gain if you optimize the SQL server. Maybe throw in a stored procedure, look at indexing etc.

    Also, this code is not safe at all for SQL injection attacks. You should use parameters.

  • more code please !!! optimized !!!

when to use Collection<T> vs List<T>

What is the best practice for when to use one vs the other?

Both implement IList<T> and hold the data in an ordered fashion, but only List expose the sorting semantics....

(edit: duplicate from here)

From stackoverflow
  • Well, based on what you say, I think you should use collection when you just need to store the data and you don't care at all in what order.

    Marc Gravell : That applies equally to either - just don't call Sort; there are much bigger differences - see the details in the "duplicate from here" thread)
  • in this question you can see the difference between list and collection of T

  • Scott Hanselman asked this question once. You can read his related blog post here.

  • Collection<T>:

    Provides the base class for a generic collection.

    List<T>:

    Represents a strongly typed list of objects that can be accessed by index. Provides methods to search, sort, and manipulate lists.

    So, according the docs, one is intended as a base class for collections. The other is intended for use as a container.

    So use the List and inherit from the Collection.

Post from one controller action to another (not redirect)

Hey all!

I have an action which I need to post forward onto another action if it meets certain conditions, but I am unable to preserve the form data when passing through to the next action.

The receiving action accepts a FormCollection, which the sending action

Currently, I am doing a return RedirectToAction("action","controller", form). And I can determine that the form variable has keys before it redirects (form.HasKeys() = true).

When the action is hit however, the FormCollection is empty (form.HasKeys() = false).

Any ideas? Is there a 'PostToAction' method that I am missing?

FYI: I am using ASP.NET MVC Beta. Many thanks!

From stackoverflow
  • I would refactor the two controllers and put the common code into a helper or into a common base class. That way the actions in the two controllers can delegate to the common code.

  • When RedirectToAction is called it will make an HTTP redirection and it will make a GET to the other action URL. If you need to reuse the code from another controller I'd do what ewalshe suggest, move the common to a BaseController or a business service and make both actions delegate to it.

    This links may help:

    Dan Atkinson : Eduardo, thankyou for the linkage! It helped looking at Stephen Walther's example.

C# Can I nullify an object from another class

I have an object that is generated in one class

public class CreatingClass
{
    public T CreateObject<T>(Dictionary<string, object> parameters) where T : IMyInterface, new()
    {
        ....
    }

    public void DestroyObject(IMyInterface objectToDestroy)
    {
        ....
    }
}

I call this function from a client class, then at times need to nullify it through my application by the creating class.

Can I do something like the following

public class ClientClass
{
    MyObject obj;
    CreatingClass creatingClass = new CreatingClass();

    private void AFunctionToCreateMyClass()
    {
        obj = creatingClass.CreateObject<MyClass>(parameters);
    }

    private void AFunctionToDeleteMyObject()
    {
        CreatingClass.DestroyObject(obj);
        Assert.IsNull(obj);//Doesn't fail
    }
}

I had tried objectToDestroy = null, but didn't think it would work (and it didn't)

From stackoverflow
  • What you want is

    public void DestroyClass(ref IMyInterface objectToDestroy)
    {
        ....
        objectToDestroy = null;
    }
    

    This is will set your local reference to null

    johnc : Makes complete sense
    GvS : But will only set one reference to the object to null. The object itself is not destroyed, and other references to it are still valid.
    DrJokepu : GvS: That's pretty much true for every object in a garbage collected environment. That's why (amongst other reasons) it is a good idea to minimize the number of references to an object.
  • [Your 'CreatingClass' is usually termed a factory]

    Not sure why you'd be concerned with nullifying an object; it will be garbage collected only after all 'root' references to it have been removed. But if you change to:

     public void DestroyClass(ref IMyInterface objectToDestroy)   
     {       
         ....    
         objectToDestroy = null;
     }
    

    and call as:

    private void AFunctionToDeleteMyObject()    
    {        
       CreatingClass.DestroyObject(ref obj);    
       Assert.IsNull(obj);  
    }
    
  • All parameters in C# are passed by value, so if you want to modify the reference itself, you need to pass it using the ref keyword.

  • Are you looking for the IDisposable pattern?

  • Note that you can't actually destroy an object; you are subject to the rules of garbage collection. At a push, you could check for IDisposable and call Dispose(),

    You can use the ref samples provided, but I'm not sure there is much point; it is simpler just to clear the field with "obj = null;".

    The ref usage could get confusing, since that works on the variable - i.e. if you do:

    var tmp = obj;
    DestroyObject(ref tmp);
    

    then obj will still be the original value. Unless you have a good reason, I don't recommend the ref approach.

    Mitch Wheat : +1. Nice reference count example.
    Marc Gravell : That isn't a "reference count example"; it simple illustrates how "ref" works on the variable not the object... GC doesn't use reference counting
    Binary Worrier : +1: Far more complete answer than mine.
    Joe : Also, it's almost always better not to set "obj = null". Just leave the GC to decide when an object is no longer used.
    Mitch Wheat : @Marc: "reference count " was the wrong words to use. I meant it nicely shows how having a ref stops it being GC'd
  • A little clarification on the answers supplied...

    Parameters in C# are passed by their type, value for value types, reference for reference types. You however, are passing an interface which could relate to a class (reference type) or struct (value type), therefore you need to explicitly declare it as a ref variable.

    However, what you should really follow (as mentioned previously) is the IDisposable pattern, which was designed for this functionality.

    EDIT: Parameters are passed by value, but for reference types the reference is the value. Therefore is you destroy the refence in the function, the original reference type is unaffected. If you make a change to the reference variable, i.e. modifying data in a dataset, the original reference type is updated outside of the function.

    Jon Skeet : No, parameters are *always* passed by value by default. For reference types, the parameter value *is* the reference - but that's passed by value. See http://pobox.com/~skeet/csharp/parameters.html
    Marc Gravell : "If you make a change to the reference variable, i.e. modifying data in a dataset" - modifying a dataset is modifying the instance, not the variable. There is an important difference.

Get most frequently used applications in VB.NET

Is there a way that I can get the most used applications via VB.NET? I'm developing a sort of hobby project as a quick launcher kind of thing and thought this would sit perfectly on the main form.

If possible, would somebody be able to explain to me how add/remove applications manages to get the frequency of used applications? It would be good if I could get it in a list like the XP/Vista start menu as well.

Any guidance would be greatly appreciated. :)

From stackoverflow
  • This might be a decent place to start. It seems like windows does a crappy job of determining frequency of applications use.

    http://blogs.msdn.com/oldnewthing/archive/2004/07/09/178342.aspx

  • According to this posting the information is stored in the first 28 bytes of the SlowInfoCache Registry value found at the following key:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Management\ARPCache
    

    The format of the value is (in VB.Net):

    Structure SlowInfoCache
            Dim cLen As Integer         ' size of the SlowInfoCache (552 bytes)
            Dim Flag As Boolean         ' has a name
            Dim Size As Long            ' program size in bytes
            Dim LastUsed As Long        ' API-style FILETIME
            Dim Frequency As Integer    ' 0-2 = rarely; 3-9 = occassionaly; 10+ = frequently
            Dim Path As String          ' remaining 524 bytes (max path of 260 + null) in unicode
    End Structure
    

    If you are interested in the other information displayed in Control Panel -> Add or Remove Programs you will find it listed for each product under the following Registry key:

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
    
  • It looks like you can find information on how often a program is run in the registry key:

    HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist\
    

    There's more explanation here and a .NET program here that you could reverse engineer to get at the count values using VB.Net.

  • Or course these solutions only track when the shell (explorer.exe) is used to start a program via a shortcut (all start menu items are shortcuts). That's why it is so inaccurate.

    FWIW I'm not aware of any microcomputer operating system that tracks the execution frequency of program images.

    I suggest for your launcher tool that you initially popule it with the shortcuts from the quicklaunch bar and just make it really easy for the user to configure rather than trying to do anything automatic - automatic stuff that doesn't work in the way the user expects is one of the most annoying aspects of user interface design.

    brien : For the start menu at least, the program earns points, not the shortcut: http://blogs.msdn.com/oldnewthing/archive/2007/06/13/3258912.aspx
  • One question you should ask yourself is how are you going to determine frequency?

    Are you going to base it on the number of times and application is run, or based on the length of time that an application is run for?

Function-level constants - declare at top of function?

I have a constant value that I only plan to use once in my codebase. I am going to declare it using a const declaration.

If this was a function-level variable I would declare it at the point of usage, but doing so with a constant just seems to clutter my function.

From stackoverflow
  • I look a constants as a kind of configuration. If they can change they become application properties, if they can't I put them at the top of the class in which they will be used even for function level constants.

    This way you can just open the file and see them all in one list

  • The two reasons for using a constant instead of hard-coding a value is for readability and so it can be easily found and changed later, right? So declare it where it would be most easily found later. Usually I find this is at the beginning of the function, class, or file - again, whatever scope makes sense.

  • I usually declare them as close to where I'll use them as possible.

    Reason is that when I'm going through other people's code, it's very inconvenient to have to jump up and down a file to understand what's going on. So I try to make it easy on others when writing code myself.

    For small(ish) function at the top of the function could increase readability (and hence understandability for others), so this rule is far from etched in stone.

  • I put them in the beginning of the file, treats them as configuration all over the class. Also while coding just mouse-over and regardless of the location your shiny IDE will tell you the value of it.

    It's not something you keep changing if it's don't introduce your constant yet, code it, try whatever you want then when you done refactor, and make it a constant.

Do you find source code analyzers useful?

  • Do you use source code analyzers? If so, which ones and for which language development?
  • Do you find them helpful in solving potential bugs in your code? Or are most of their warnings trivial?
  • After prolonged use, do you find your code quality to be higher than before?
From stackoverflow
  • I'm a long term user of PC-Lint for C and C++ and find it very helpful. These tools are most useful when taking over a code base you are unfamilier with. Over time you hit a law of diminishing returns, where the number of new bugs you find tends to trail off.

    I always still to a full project lint on a big release.

    Edit: There is a nice list of relevent tools on Wikipedia here

    aku : lint preforms static code analysis it's not a "source code" analyzer
    GaryF : Aren't the two terms interchangeable?
    Shane MacLaughlin : Source code analysis is generally static, and pc-lint is a static source code analyser which focusses on finding bugs rather than formatting style. Could you name a dynamic source code analyser? ;)
    aku : 2 smcal, static analysis tool operates on binary level it doesn't parse source code to detect errors, for example ReSharper analyze code on the fly - it doesn't require you to build code to find out unused variables
    Shane MacLaughlin : @aku, not by my understanding of the term. Static analysis is any analysis of code (source or binary) that is not being executed, e.g. lint. Dynamic analysis is analysis of code in-situ as it is executing. FWIW, Wikipedia agrees with me, see http://en.wikipedia.org/wiki/Static_code_analysis
    aku : smcal, yep you're right. by "source analysis" I meant tools such as StyleCop, I agree that I was wrong with previous statement
  • I use StyleCop for C#. It's a great tool to keep consistent code style that leads to better code quality. Also ReSharper does some code analysis but it's pretty basic.

    Shane MacLaughlin : Which static analysis tools do you use for C and C++ that don't analyse the source code?
    aku : smcal, which static analysis tools do you know that analyze source code (i.e. parse source code files) ?
    Shane MacLaughlin : @aku, lint is the one that I use, and probably the longest such tool in use. Please see the following link for a list of static analysis tools; http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis
    aku : smacl, I been too strict on terminology, by "source analysis" I meant tools that perform source code parsing. for example FxCop operates on MSIL level (it parse binary files)
  • I use a few static analysis tools in Java. FindBugs is the first line of defense, catching a lot of common errors and giving pretty useful feedback. It often spots the silly mistakes of tired programmers and doesn't place a high burden on the user.

    PMD is good for a lot of other more niggly bugs, but requires a lot more configuration. You'll find that PMDs defaults are often over the top. There are too many rules that are probably beneficial on a tiny scale but ultimately don't help other programmers maintain your code. Some of the PMD rules often smack of premature optimisation.

    Probably more useful is the CPD support in PMD. It attempts to find code that has been duplicated elsewhere, in order to make refactoring much easier. Run over an entire project, this really helps determine where the biggest priorities are for cleaning up code and stopping any DRY violations.

    Checkstyle is also handy, making sure your coders conform to some coding style standard. it has a bit of overlap with PMD but is generally much more usable.

    Finally, Cobertura is a great test coverage suite. Very handy for finding out where the unit tests are lacking, and where you should be prioritising the creation of new tests.

    Oh, and I've also been testing out Jester. It seems to be pretty good for finding holes in tests, even where the code has some coverage. Not recommended yet, simply because I've not used it enough, but one to test out.

    I run these tools both from within Eclipse and as part of an automated build suite.

    Yuval A : +1 Really thorough answer :)
  • For C, I use MEMWATCH. It's really easy to use and free.

    I've used it to find many memory bugs in the past.

    Shane MacLaughlin : This is a dynamic analysis tool, not a source code analyser.
  • I'm pretty happy with ReSharper. Not only does it give useful bits of information while coding (e.g. needless casts, apply readonly and so forth) but its refactoring features are excellent for rearranging the code very quickly.

    It doesn't cover everything, so FxCop (or similar) is a decent addition to the toolbox. However, as Resharper gives immediate feedback, the turnaround time is really good. (I'm aware that FxCop can be run from VS, but its just not the same imo).

  • I used resharper and MS TS (basically FXCop) and both of them quite usefull especially in the following areas :

    • Identifying dead code
    • Wide Scope
    • Performance improvements (related with globalization etc.)

    Recommendations are not always great but generally improved the quality of the code.

  • I find analyzers somewhat useful, i use the buildin to visual studio (ex. /analyze for c/c++ and the custom rules for .net), occasionally i use stylecop and codeitright for c# mostly for guidelines how things should be.

    I don't think there is a perfect tool for everything, that finds every bug, but i think the tools help to find some bugs, not untraceable, but believe me you would spend a ton of time finding them.

    Yes your code quality is SOMEWHAT better than before, but i also believe manual debugging is still needed alot. Source analyzers are not the ultimate cure they are a good medicine though. If there was a tool that you just execute it and find any kind of bugs and fixes it for you would cost millions.

    Some programmers that i know swear that IBM Rational PurifyPlus is superb, but that is their opinion i just had 2-3 sessions with the tool.

    But always remember one of the basic principles of programming logical errors are the hardest for find and fix, so long debugging hours are inevitable. A good code analyzer combined with unit testing may work miracles thought.

    PS. i tend to produce far less errors in C# than in C++, someone may say i am wrong but although i use c++ more years than c# i find the "code it and i will take care of it" gc approach of C# far easier than c++ especially for projects you rush thing to finish at the time limit/deadline, which EVERY project is like this days...

How to scroll a panel manually?

I want to use the same functionality available when a Panel.AutoScroll is true, but with the scrollbars invisible.

To do so I need to know how can I scroll to left/right up/down using functions in my code.

From stackoverflow
  • You should be able to use the VerticalScroll and HorizontalScroll properties of the component:

    c.HorizontalScroll.Value += 100;
    c.VerticalScroll.Value = c.VerticalScroll.Maximum;
    
    Jonas : It works only when AutoScroll=true, but then I can't hide the HorizontalScroll/VerticalScroll. Setting the Scroll.Visible=false doesn't hide the scroll)
  • There's probably a property on the panel to do this, alternatively you can loop through all the panels children and adjust their positions.

    Eg. to move all controls 10 px:

    int xoffset = 10;
    
    foreach(Control c in panel1.Controls)
        c.Location.X += xoffset;
    

    The controls can be moved to negative positions to make them move out of the panel, similarly they can have location values bigger than the panels size to make them move out of the panel.

    fallenidol : don't think you can set the location to -ve values.
    sindre j : fallenidol : That is just plain wrong! Try it yourself, if you set the .Left property of a control to say -10 it will move left of the border of the container.
  • Well if you don't want to use the Autoscroll property, there's a way that I used a long time ago.

    • Put a panel inside the panel. Put the scrollbar control on the parent panel, and then use the scrollbar to change the Top property of the panel inside.

    It's simple and works beautifully.

JMF and RTP Protocol

Hello everyone.

I am doing a project which consists of a video-conference system in Java and using the RTP protocol.

The problem is that I can not pass the stream to the clients, that I capture in my webcam.

Someone can give me a hand.

I already turned off my firewall, but does not waork.

Thank you

From stackoverflow
  • Hello, i´m doing the same project with the author.

    We are two applications, a server, that send stream of video and voice to client. The client receive stream and shows to user.

    The problem is send stream from server to client... The examples of SUN´s forum and other don´t work.

    Any idea?

  • Try to look at the network traffic, e.g. with Wireshark.

  • Anyone have any example of such a system to work.

    Would I could borrow?

How to run test cases on a list of slightly different jars ?

I have a list of jar files, all containing slightly different versions of the same system.

I want to execute a set of test cases on each jar file while being able to obtain the results for each jar (via RunListener or something like that).

I am a bit confused with the class loading problems that are implied.

How can I nicely do this ?

From stackoverflow
  • If the jars maintain the same interface, then all you have to do is run each test with a slighly different classpath - each time with jars from another version.

    If you're using Eclipse JUnit integration, just create N run configurations, in each one in the classpath tab specify required jars.

    If you want to do it programmatically, then I suggest you start with empty classpath and use URLClassLoader, giving it a different set of jars each time.

    Something like this:

    URLClassloader ucl = new URLClassLoader( list of jars from version1 );
    TestCase tc = ucl.loadClass("Your Test Case").newInstance();
    tc.runTest();
    
    ucl = new URLClassLoader( list of jars from version2 );
    TestCase tc = ucl.loadClass("Your Test Case").newInstance();
    tc.runTest();
    
  • If you are using ant, the JUnit task takes a classpath.

    <target name="test">
      <junit ...">
        <classpath>
          <pathelement path="${test.jar.path}" />
        </classpath>
        ...
      </junit>
    </target>
    

    You can use the antcall task to call your test target repeatedly with a differed value for the test.jar.path property.

MySQL partitioning with ActiveRecord

I want to take advantage of the new partitioning in MySQL 5.1 but using a standard ActiveRecord model. The problem I have encountered is that to use the partitioning the primary key on the table must include the columns used in the partitioning function. (http://dev.mysql.com/doc/refman/5.1/en/partitioning-limitations-partitioning-keys-unique-keys.html)

Now, I want to have a auto-incrementing 'id' field (which is usually used as the primary key in Rails) but I want to partition using another column, in this case 'task_id'. Crucially I don't want to use composite primary keys in my Rails application. My question is this:

If I set up the table as follows:

"CREATE TABLE `annotations` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `task_id` int(11) DEFAULT NULL,
  `user_id` int(11) DEFAULT NULL,
  `value` text,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`, `task_id`),
  KEY `index_annotations_on_task_id` (`task_id`),
  KEY `index_annotations_on_user_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
PARTITION BY RANGE(task_id)(
PARTITION 1_to_5 VALUES LESS THAN (6),
PARTITION 6_to_10 VALUES LESS THAN (11),
PARTITION 11_to_15 VALUES LESS THAN (16))"

where I have the primary key composed of the 'id' and 'task_id' columns, and I don't do anything special with the ActiveRecord model, am I setting myself up for any headaches in the future?

Basically, I'm creating a table with a primary key based upon two columns but not telling ActiveRecord about the second column as I still have an auto-incrementing id field - can anyone see any problems with this approach?

From stackoverflow
  • I believe what you describe, create the ActiveRecord model then alter it directly in MySQL will work. The possible down side is that Rails will not know about 'task_id' and of course would not include it in the queries. The problem being that the major advantage of partitioning is the query optimizer would see that the query included "task_id = 7" and know the query only needed to be run in the second partition.

    You should still see some advantages as joins (particularly from the task table) would include this key and the query optimizer could do the right thing.

    Rails / Active Record also has a habit of updating every column regardless of if it has changed. MySQL usually would notice your were updating a column to the value that it was already - but watch this because if MySQL thinks it needs to move a record from one partition to another your updates would take a hit.

  • Although not exactly what you are looking for, as an alternative have you seen DataFabric? It is an application level way of sharding your data across multiple databases. It also gives you a way to use master->slave replication. Like I said, not exactly the same as database level partitioning, but seems like it would be easier to implement.

  • OK, thanks for your comments. Yes I have been looking at DataFabric and this looks to have some pretty useful features for sharding and replicating databases. Anyway, thanks for the input, I'll have to read around a little more before making a decision.